रिएक्ट JSX के अंदर लूप


1278

मैं रिएक्ट में निम्नलिखित की तरह कुछ करने की कोशिश कर रहा हूं JSX(जहां ObjectRow एक अलग घटक है):

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

मुझे पता है और समझते हैं कि यह मान्य क्यों नहीं है JSX, क्योंकि JSXनक्शे कॉल करने के लिए कार्य करते हैं। हालाँकि, टेम्प्लेट लैंड से आना और नया होना JSX, मैं अनिश्चित हूं कि मैं उपरोक्त (एक घटक को कई बार जोड़ते हुए) कैसे प्राप्त करूंगा।


38
यह ध्यान रखना महत्वपूर्ण है कि JSX में आपको अपने जावास्क्रिप्ट सिंटैक्स के आसपास {} टैग्स की आवश्यकता है। यह facebook.github.io/react/docs/… की मदद कर सकता है ।
यशायाह ग्रे

30
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
ओवरकोडर


@OverCoder आप पूरे रिटर्न को {} टैग में क्यों डालेंगे = यह होगा => रिटर्न <h1> {todo.title} </ h1> क्या यह नहीं है?
प्रवीण पौडेल

1
@pravinpoudel वास्तव में यह उत्तर पुराना है, अधिक पसंद let todos = this.props.todos.map(t => <h1>{t.title}</h1>):) :)
ओवरकोडर

जवाबों:


1204

इसे ऐसे समझें कि आप केवल जावास्क्रिप्ट फ़ंक्शन कह रहे हैं। आप एक forलूप का उपयोग नहीं कर सकते जहां एक फ़ंक्शन कॉल के लिए तर्क जाएंगे:

return tbody(
    for (var i = 0; i < numrows; i++) {
        ObjectRow()
    } 
)

देखें कि फ़ंक्शन tbodyको forतर्क के रूप में एक लूप कैसे पारित किया जा रहा है, और निश्चित रूप से यह एक वाक्यविन्यास त्रुटि है।

लेकिन आप एक सरणी बना सकते हैं, और फिर उसे एक तर्क के रूप में पास कर सकते हैं:

var rows = [];
for (var i = 0; i < numrows; i++) {
    rows.push(ObjectRow());
}
return tbody(rows);

JSX के साथ काम करते समय आप मूल रूप से समान संरचना का उपयोग कर सकते हैं:

var rows = [];
for (var i = 0; i < numrows; i++) {
    // note: we add a key prop here to allow react to uniquely identify each
    // element in this array. see: https://reactjs.org/docs/lists-and-keys.html
    rows.push(<ObjectRow key={i} />);
}
return <tbody>{rows}</tbody>;

संयोग से, मेरा जावास्क्रिप्ट उदाहरण लगभग वही है जो JSX का उदाहरण है। JSX कैसे काम करता है, इसके बारे में महसूस करने के लिए बैबल REPL के साथ खेलें ।


3
यह संभव है कि संकलक बदल गया है, क्योंकि यह उदाहरण jsx संकलक में संकलित करने के लिए प्रतीत नहीं होता है , लेकिन नीचे दिए गए FakeRainBrigand के उत्तर में मानचित्र का उपयोग करना सही ढंग से संकलित लगता है।
आरएवी

9
मैं वादा कर सकता हूं कि अंतिम उदाहरण अभी भी नवीनतम JSX संकलक पर सही ढंग से संकलित है।
सोफी अल्परट

3
यह अच्छा काम करता है। FakeRainBrigand का जवाब सरल सरणी पुनरावृत्ति के लिए काम करता है, लेकिन यह उत्तर उन परिदृश्यों के लिए बहुत जरूरी है, जहां आप उपयोग नहीं कर सकते हैं map(जैसे आपके पास एक संग्रह में संग्रहित संग्रह नहीं है)।
केल्विन

52
प्रतिक्रिया को प्रभावी रूप से डोम को अपडेट करने की आवश्यकता है, इस मामले में, माता-पिता keyको प्रत्येक शिश्न को असाइन करना चाहिए । REF: facebook.github.io/react/docs/…
qsun

7
यह उदाहरण काम करेगा, लेकिन यह keyसंपत्ति जैसे कुछ महत्वपूर्ण बिट्स को याद करता है और एक कोड शैली भी है जो वास्तव में रिएक्ट कोड-बेस में उपयोग नहीं की जाती है। कृपया इस उत्तर पर विचार करें stackoverflow.com/questions/22876978/loop-inside-react-jsx/… एक सही के रूप में।
okonetchnikov

865

सुनिश्चित नहीं है कि यह आपकी स्थिति के लिए काम करेगा, लेकिन अक्सर मानचित्र एक अच्छा जवाब है।

यदि यह लूप के लिए आपका कोड था:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    } 
</tbody>

आप इसे मानचित्र के साथ इस तरह लिख सकते हैं :

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>

ES6 सिंटैक्स:

<tbody>
    {objects.map((object, i) => <ObjectRow obj={object} key={i} />)}
</tbody>

43
यदि नक्शा एक सरणी है तो मानचित्र और अधिक समझ में आता है; लूप के लिए उपयुक्त है यदि यह एक संख्या है।
कोड व्हिस्परर

26
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>Reactify के ES6 सपोर्ट या बैबल का उपयोग करना।
डिस्टॉर्टम

3
+1। मैं भी एक उल (unordered सूची) के साथ यह प्रयोग कर रहा हूँ। <ul> {objects.map((object:string,i:number)=>{ return <li>{object}</li> })} </ul>टाइपस्क्रिप्ट का उपयोग करना
रॉबर्टो सी नवारो

5
इस महान है, लेकिन आप एक वस्तु पर मैप नहीं कर सकते .. कि मैं का प्रयोग करेंगे के लिएfor..in
डैमन

4
यह ध्यान रखें कि Object.keys का उपयोग करते समय कुंजियों का क्रम मनमाना होता है। मुझे लगता है कि कुंजी के क्रम को अलग-अलग रखने से अच्छा काम होता है, और यदि आवश्यक हो तो वस्तु शाब्दिक पर भी आदेश। इससे मुझे कोड लिखने की अनुमति मिलती हैthis.props.order.map((k)=><ObjectRow key={k} {...this.props.items[k]} />)
8

443

यदि आपके पास map()@ FakeRainBrigand का उत्तर पसंद करने के लिए पहले से कोई सरणी नहीं है , और यह इनलाइन करना चाहते हैं, तो स्रोत लेआउट @ SophieAlpert के उत्तर की तुलना में आउटपुट के करीब है:

ES2015 (ES6) सिंटैक्स के साथ (प्रसार और तीर फ़ंक्शन)

http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview

<tbody>
  {[...Array(10)].map((x, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

पुन: बैबेल के साथ ट्रांसप्लिंग, इसका कैविट्स पृष्ठ कहता है कि Array.fromप्रसार के लिए आवश्यक है, लेकिन वर्तमान में ( v5.8.23) ऐसा प्रतीत नहीं होता है जब वास्तविक फैलता है Array। मेरे पास स्पष्ट करने के लिए एक प्रलेखन मुद्दा खुला है। लेकिन अपने जोखिम या पॉलीफिल पर उपयोग करें।

वेनिला ईएस 5

Array.apply

<tbody>
  {Array.apply(0, Array(10)).map(function (x, i) {
    return <ObjectRow key={i} />;
  })}
</tbody>

इनलाइन IIFE

http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview

<tbody>
  {(function (rows, i, len) {
    while (++i <= len) {
      rows.push(<ObjectRow key={i} />)
    }
    return rows;
  })([], 0, 10)}
</tbody>

अन्य उत्तरों से तकनीकों का संयोजन

आउटपुट के अनुरूप सोर्स लेआउट रखें, लेकिन इनलाइन हिस्से को अधिक कॉम्पैक्ट बनाएं:

render: function () {
  var rows = [], i = 0, len = 10;
  while (++i <= len) rows.push(i);

  return (
    <tbody>
      {rows.map(function (i) {
        return <ObjectRow key={i} index={i} />;
      })}
    </tbody>
  );
}

ES2015 सिंटैक्स और Arrayविधियों के साथ

साथ Array.prototype.fillआप प्रसार उपयोग का एक विकल्प के रूप में ऐसा कर सकता है इसके बाद के संस्करण दिखाया गया है:

<tbody>
  {Array(10).fill(1).map((el, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

(मुझे लगता है कि आप वास्तव में किसी भी तर्क को छोड़ सकते हैं fill(), लेकिन मैं उस पर 100% नहीं हूं।) fill()समाधान के पुराने संस्करण में मेरी गलती को सुधारने के लिए @FakeRainBrigand का धन्यवाद (संशोधन देखें)।

key

सभी मामलों में keyअटेर विकास बिल्ड के साथ एक चेतावनी को कम करता है, लेकिन बच्चे में सुलभ नहीं है। यदि आप बच्चे में उपलब्ध इंडेक्स चाहते हैं, तो आप एक अतिरिक्त एटर पास कर सकते हैं। चर्चा के लिए सूचियाँ और कुंजी देखें ।


2
किस बारे में yield? जब हम जनरेटर होते हैं, तो इंटरमीडिएट सरणी में तत्वों को धक्का देना बदसूरत होता है। क्या वे कार्य करते हैं?
एमपीएन

2
@ मर्क मैं नहीं जानता कि जनरेटर वास्तव में यहाँ लागू होते हैं। JSX के संदर्भ में इसके लिए महत्वपूर्ण बात एक अभिव्यक्ति है जो एक सरणी देता है। इसलिए यदि आप किसी जनरेटर का उपयोग करने जा रहे हैं, तो आप इसे वैसे भी फैला देंगे, और यह शायद ES2015- आधारित समाधानों की तुलना में अधिक क्रियात्मक होगा।
JMM

2
कैसे है यह अधिक वर्बोज़? और JSX किसी भी चलने योग्य को स्वीकार नहीं करेगा, न कि केवल सरणियों को?
एमपीएन

2
@ मर्क वह वास्तव में (ईएस 5) आईआईएफई उदाहरण की तुलना में कम क्रिया है, लेकिन यह [...Array(x)].map(() => <El />))संस्करण की तुलना में काफी अधिक क्रिया है , जो मुझे लगता है कि सबसे सुरुचिपूर्ण है, और मैंने इसे क्यों चित्रित किया। पुन: दूसरा सवाल, यह एक महान बिंदु है। JSX के बारे में कुछ भी ऐसा प्रतीत नहीं होता जो इसे प्रस्तुत करता हो, इसलिए यह निर्भर करता है कि रूपांतरित JSX का कोई अन्य उपभोक्ता क्या तर्क देता है, जो बच्चों के तर्कों के साथ है, जिसे मैं स्रोत को देखे बिना नहीं कह सकता। क्या आप जानते हैं? यह एक पेचीदा सवाल है।
झामुमो

3
@ कोरसेंटीमन्स कूल, इस जानकारी के लिए धन्यवाद fill()। मुझे अब याद है कि जिस कारण से मैं हिचकिचाया था, यह सवाल है कि ईएस युक्ति में मापदंडों की वैकल्पिकता को कैसे दर्शाया गया है (कुछ समय में उस पर गौर करना होगा)। अल्पविराम एक तत्व तत्व को खत्म करने का एक तरीका है - इस मामले में पहले वाला। आप यह कर सकते हैं कि यदि आप चाहते हैं कि अनुक्रमणिकाएँ 1. सरणी के तरंग से हों, तो आप प्रसार सरणी के 0..length-1 के बजाय फैला रहे हैं (क्योंकि अभिभूत तत्व केवल सरणी की लंबाई और डॉन में योगदान करते हैं ' टी के पास एक समान संपत्ति है)।
जेएमएम

85

बस ES6 सिंटैक्स के साथ मैप एरे विधि का उपयोग कर :

<tbody>
  {items.map(item => <ObjectRow key={item.id} name={item.name} />)} 
</tbody>

keyसंपत्ति को मत भूलना ।


मैं एक यादृच्छिक 'Math.random ()' कुंजी की जगह आईडी जोड़ रहा हूं, यह ठीक काम नहीं कर रहा है जब बच्चों के अंदर सेटस्टैट है, तो कोई विचार है क्यों?
ओलिवर डी

82

तत्वों के एक सरणी के माध्यम से लूप के लिए ऐरे मैप फ़ंक्शन का उपयोग करना बहुत आम है और रिएक्ट में उनके अनुसार घटकों का निर्माण करें , यह एक लूप करने का एक शानदार तरीका है जो जेएसएक्स में आपके लूप्स को करने के लिए काफी कुशल और सुव्यवस्थित तरीका है , यह एकमात्र नहीं है इसे करने का तरीका, लेकिन पसंदीदा तरीका। इसके अलावा, आवश्यक के रूप में प्रत्येक पुनरावृत्ति के लिए एक अद्वितीय कुंजी होने मत भूलना । मानचित्र फ़ंक्शन 0 से एक अद्वितीय सूचकांक बनाता है, लेकिन उत्पादित सूचकांक का उपयोग करने की अनुशंसा नहीं की जाती है, लेकिन यदि आपका मूल्य अद्वितीय है या यदि कोई अद्वितीय कुंजी है, तो आप उनका उपयोग कर सकते हैं:

<tbody>
  {numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>

इसके अलावा, एमडीएन से कुछ पंक्तियाँ यदि आप ऐरे पर मानचित्र कार्य से परिचित नहीं हैं:

नक्शा किसी दिए गए कॉलबैक फ़ंक्शन को एक बार में प्रत्येक तत्व के लिए एक क्रम में कॉल करता है, और परिणामों से एक नया सरणी बनाता है। कॉलबैक केवल उसी सरणी के अनुक्रमित के लिए लागू किया जाता है, जिसमें अपरिभाषित सहित मान निर्दिष्ट किए गए हैं। इसे एरे के लापता तत्वों के लिए नहीं कहा जाता है (अर्थात, ऐसे इंडेक्स जो कभी सेट नहीं किए गए हैं, जिन्हें हटा दिया गया है या जिन्हें कभी कोई मान नहीं सौंपा गया है)।

कॉलबैक को तीन तर्कों के साथ लागू किया जाता है: तत्व का मूल्य, तत्व का सूचकांक और सरणी वस्तु का पता लगाया जा रहा है।

यदि यह एक आर्ग पैरामीटर को मानचित्र प्रदान किया जाता है, तो इसे कॉलबैक के इस मान के रूप में उपयोग किया जाएगा। अन्यथा, अपरिभाषित मूल्य को इसके मूल्य के रूप में उपयोग किया जाएगा। यह मूल्य अंततः कॉलबैक द्वारा देखा जा सकता है, जो कि किसी फ़ंक्शन द्वारा देखे गए इसे निर्धारित करने के सामान्य नियमों के अनुसार निर्धारित किया जाता है।

नक्शा उस सरणी को म्यूट नहीं करता है जिस पर इसे कहा जाता है (हालांकि कॉलबैक, यदि आह्वान किया जाता है, तो ऐसा हो सकता है)।


Array#mapAsync नहीं है!
दर्शन १

52

यदि आप पहले से ही लॉश का उपयोग कर रहे हैं, तो _.timesफ़ंक्शन आसान है।

import React, { Component } from 'react';
import Select from './Select';
import _ from 'lodash';

export default class App extends Component {
    render() {
        return (
            <div className="container">
                <ol>
                    {_.times(3, i =>
                        <li key={i}>
                            <Select onSelect={this.onSelect}>
                                <option value="1">bacon</option>
                                <option value="2">cheez</option>
                            </Select>
                        </li>
                    )}
                </ol>
            </div>
        );
    }
}

1
Array.prototype.map यहां एक बढ़िया विकल्प हो सकता है यदि आप किसी लाइब्रेरी जैसे कि लॉश को शामिल नहीं कर रहे हैं। developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
यशायाह ग्रे

1
@IsaiahGrey केवल अगर आपको पहले से ही एक सरणी मिल गई है। कभी-कभी आप सामान को कुछ बार दोहराना चाहते हैं।
एमपीएन

1
बिलकुल ही! वास्तविक आंकड़ों के आधार पर लॉट के विभिन्न दृष्टिकोण। मैंने पाया कि हमारी विकास प्रक्रिया में अधिक बार हम इस बात के लिए मानचित्र फिट नहीं कर पाए हैं कि मॉडल कैसे बनाए जाते हैं। लताश का उपयोग कर महान उदाहरण! Btw, क्या आप अपने घटकों को अपने तरीकों से बांधने के लिए संपत्ति इनिशियलाइज़र सिंटैक्स का उपयोग कर रहे हैं?
यशायाह ग्रे

4
@IsaiahGrey मुझे लगता है कि उन्हें सिर्फ ES6 विधि परिभाषाएँ
16:22 पर mp


34

मुझे पता है कि यह एक पुराना धागा है, लेकिन आप रिएक्ट टेम्प्लेट को चेकआउट करना चाह सकते हैं , जो आपको प्रतिक्रिया में jsx- शैली के टेम्प्लेट का उपयोग करने देता है, कुछ निर्देशों (जैसे आरटी-रिपीट) के साथ।

आपका उदाहरण, यदि आपने प्रतिक्रिया-टेम्पलेट का उपयोग किया है, तो यह होगा:

<tbody>
     <ObjectRow rt-repeat="obj in objects"/>
</tbody>

अतिरिक्त पुस्तकालय का उपयोग क्यों करता है जबकि समस्या को हल करने के लिए सादे जावास्क्रिप्ट ने पहले से ही या तो विभिन्न प्रकार के लूप या Array.prototype.map विधि के साथ समाधान प्रदान किया है? मैंने स्वयं अपने वर्तमान प्रोजेक्ट में पहले से ही सादे जावास्क्रिप्ट तरीके दोनों का उपयोग किया है जो अच्छी तरह से काम करते हैं। जब भी संभव हो मुझे जावास्क्रिप्ट जावास्क्रिप्ट तरीके का उपयोग करने की आदत है, मुझे जावास्क्रिप्ट में अपने कौशल को बेहतर बनाने में मदद करता है। मैं केवल अतिरिक्त पुस्तकालयों का उपयोग करता हूं जब कुछ समस्याओं के समाधान ढूंढना मुश्किल लगता है, जैसे रिएक्ट-राउटर के साथ रूटिंग।
लेक्स सॉफ्ट

27

ऐसा करने के बारे में कई तरीके हैं। JSX अंततः जावास्क्रिप्ट के लिए संकलित हो जाता है, इसलिए जब तक आप वैध जावास्क्रिप्ट लिख रहे हैं, तब तक आप अच्छे होंगे।

मेरा जवाब यहाँ पहले से ही प्रस्तुत सभी शानदार तरीकों को मजबूत करना है:

यदि आपके पास कोई ऑब्जेक्ट नहीं है, तो बस पंक्तियों की संख्या:

returnब्लॉक के भीतर , निर्माण Arrayऔर उपयोग करना Array.prototype.map:

render() {
  return (
    <tbody>
      {Array(numrows).fill(null).map((value, index) => (
        <ObjectRow key={index}>
      ))}
    </tbody>
  );
}

returnब्लॉक के बाहर , सामान्य लूप के लिए सामान्य जावास्क्रिप्ट का उपयोग करें:

render() {
  let rows = [];
  for (let i = 0; i < numrows; i++) {
    rows.push(<ObjectRow key={i}/>);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

तुरंत समारोह अभिव्यक्ति का आह्वान किया:

render() {
  return (
    <tbody>
      {() => {
        let rows = [];
        for (let i = 0; i < numrows; i++) {
          rows.push(<ObjectRow key={i}/>);
        }
        return rows;
      }}
    </tbody>
  );
}

यदि आपके पास वस्तुओं की एक सरणी है

returnब्लॉक के भीतर , .map()एक <ObjectRow>घटक के लिए प्रत्येक वस्तु :

render() {
  return (
    <tbody>
      {objectRows.map((row, index) => (
        <ObjectRow key={index} data={row} />
      ))}
    </tbody>
  );
}

returnब्लॉक के बाहर , सामान्य लूप के लिए सामान्य जावास्क्रिप्ट का उपयोग करें:

render() {
  let rows = [];
  for (let i = 0; i < objectRows.length; i++) {
    rows.push(<ObjectRow key={i} data={objectRows[i]} />);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

तुरंत समारोह अभिव्यक्ति का आह्वान किया:

render() {
  return (
    <tbody>
      {(() => {
        const rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      })()}
    </tbody>
  );
}

2
शानदार उत्तर: विभिन्न तकनीकें, सभी केवल सादे जावास्क्रिप्ट का उपयोग करती हैं जो कि जावास्क्रिप्ट की शक्ति को दर्शाता है, इसके समान कार्य करने के विभिन्न तरीकों के लिए धन्यवाद।
लेक्स सॉफ्ट

24

यदि संख्या एक सरणी है, और यह बहुत सरल है।

<tbody>
   {numrows.map(item => <ObjectRow />)}
</tbody>

रीएक्ट में ऐरे डेटा टाइप बहुत बेहतर है, ऐरे नए ऐरे को वापस कर सकते हैं, और फिल्टर, सपोर्ट आदि को कम कर सकते हैं।


यह एक सभ्य जवाब नहीं है क्योंकि यह एक कुंजी का उपयोग नहीं करता है।
kojow7

21

mapकथन का उपयोग करने के लिए कई उत्तर दिए गए हैं। फ़ीचर घटकों को JSON डेटा संरचना नामक सुविधाओं के आधार पर सूचीबद्ध करने के लिए फ़ीचरलिस्ट के भीतर एक इट्रेटर का उपयोग करते हुए एक पूर्ण उदाहरण है

const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
  <div className="feature-list">
    {features.map(feature =>
      <Feature
        key={feature.id}
        {...feature}
        onClickFeature={() => onClickFeature(feature.id)}
        onClickLikes={() => onClickLikes(feature.id)}
      />
    )}
  </div>
); 

आप GitHub पर संपूर्ण फीचरलिस्ट कोड देख सकते हैं । सुविधाओं स्थिरता यहां सूचीबद्ध है


JSON डेटा के साथ काम करते समय, जैसे कि लाने के लिए डेटाबेस से डेटा प्राप्त करना एपीआई, मैं Array.prototyp.map विधि का उपयोग करने पर भरोसा करता हूं। यह उस उद्देश्य के लिए एक सुविधाजनक और सिद्ध तरीका है।
लेक्स सॉफ्ट

17

बार और बदले की एक संख्या के लिए पाश करने के लिए, आप इसे की मदद से प्राप्त कर सकते हैं fromऔर map:

<tbody>
  {
    Array.from(Array(i)).map(() => <ObjectRow />)
  }
</tbody>

कहाँ पे i = number of times


यदि आप प्रदान किए गए घटकों में अद्वितीय कुंजी आईडी असाइन करना चाहते हैं, तो आप प्रतिक्रिया दस्तावेज़React.Children.toArray में प्रस्तावित के रूप में उपयोग कर सकते हैं

React.Children.toArray

प्रत्येक बच्चे को सौंपी गई चाबियों के साथ एक फ्लैट सरणी के रूप में बच्चों की अपारदर्शी डेटा संरचना लौटाता है। उपयोगी है अगर आप अपने रेंडर तरीकों में बच्चों के संग्रह में हेरफेर करना चाहते हैं, खासकर यदि आप इसे नीचे जाने से पहले इस.प्रोपेसेक्लिरेन को फिर से व्यवस्थित या स्लाइस करना चाहते हैं।

ध्यान दें:

React.Children.toArray()बच्चों की सूची को समतल करते समय नेस्टेड सरणियों के शब्दार्थ को संरक्षित करने के लिए चाबियाँ बदल जाती हैं। अर्थात्, ऐरे को लौटे हुए सरणी में प्रत्येक कुंजी को उपसर्ग करता है, ताकि प्रत्येक तत्व की कुंजी इनपुट सरणी से स्कूप हो जाए।

<tbody>
  {
    React.Children.toArray(
      Array.from(Array(i)).map(() => <ObjectRow />)
    )
  }
</tbody>

17

यदि आप इसे रेंडर विधि के अंदर रिटर्न () में बदलना चाहते हैं , तो आसान विकल्प मैप () विधि का उपयोग करना होगा । नक्शे () फ़ंक्शन का उपयोग करके अपने सरणी को JSX सिंटैक्स में मैप करें, जैसा कि नीचे दिखाया गया है ( ES6 सिंटैक्स का उपयोग किया जाता है )।


मूल घटक के अंदर :

<tbody>
   { objectArray.map(object => <ObjectRow key={object.id} object={object.value}>) }
</tbody>

कृपया keyअपने चाइल्ड कंपोनेंट में जोड़ा गया गुण नोट करें । यदि आपने एक मुख्य विशेषता प्रदान नहीं की है, तो आप अपने कंसोल पर निम्न चेतावनी देख सकते हैं।

चेतावनी: एक सरणी या पुनरावृत्त में प्रत्येक बच्चे के पास एक अद्वितीय "कुंजी" प्रोप होना चाहिए।

नोट: एक आम गलती जो लोग करते हैं index, जब इसे पुनरावृत्ति करते समय कुंजी के रूप में उपयोग किया जाता है, तो indexएक कुंजी के रूप में तत्व का उपयोग करना एक पैटर्न-विरोधी है और आप इसके बारे में अधिक यहां पढ़ सकते हैं । संक्षेप में, अगर यह नहीं एक स्थिर सूची कभी नहीं का उपयोग indexकुंजी के रूप में।


अब ObjectRow घटक पर, आप ऑब्जेक्ट को उसके गुणों से एक्सेस कर सकते हैं।

ObjectRow घटक के अंदर

const { object } = this.props

या

const object = this.props.object

यह आपको ऑब्जेक्ट जो आप मूल घटक से पारित करने के लिए ObjectRow घटक objectमें चर लाने चाहिए । अब आप अपने उद्देश्य के अनुसार उस वस्तु में मूल्यों को थूक सकते हैं।


संदर्भ:

जावास्क्रिप्ट में नक्शा () विधि

ECMA स्क्रिप्ट 6 या ES6


16

आइए हम कहते हैं कि हमारे पास आपके राज्य में एक आइटम है:

[{name: "item1", id: 1}, {name: "item2", id: 2}, {name: "item3", id: 3}]

<tbody>
    {this.state.items.map((item) => {
        <ObjectRow key={item.id} name={item.name} />
    })} 
</tbody>

मुझे लगता है कि आपको नक्शे (आइटम) के बाद {} से छुटकारा पाने की आवश्यकता हो सकती है, जो मुझे उनके लिए काम करने लगता था।
इयान

15

एक ES2015 / बैबल संभावना जेएसएक्स की एक सरणी बनाने के लिए एक जनरेटर फ़ंक्शन का उपयोग कर रही है:

function* jsxLoop(times, callback)
{
    for(var i = 0; i < times; ++i)
        yield callback(i);
}

...

<tbody>
    {[...jsxLoop(numrows, i =>
        <ObjectRow key={i}/>
    )]}
</tbody>

15

... या आप वांछित आउटपुट के लिए किसी ऑब्जेक्ट की एक सरणी भी तैयार कर सकते हैं और इसे फंक्शन में मैप कर सकते हैं। मैं इसे पसंद करता हूं, क्योंकि यह मुझे रेंडरिंग की वापसी के अंदर कोई तर्क के साथ कोडिंग की अच्छी प्रथा को बनाए रखने में मदद करता है।

render() {
const mapItem = [];
for(let i =0;i<item.length;i++) 
  mapItem.push(i);
const singleItem => (item, index) {
 // item the single item in the array 
 // the index of the item in the array
 // can implement any logic here
 return (
  <ObjectRow/>
)

}
  return(
   <tbody>{mapItem.map(singleItem)}</tbody>
  )
}

15

बस .map()अपने संग्रह के माध्यम से लूप का उपयोग करें और <ObjectRow>प्रत्येक पुनरावृत्ति से सहारा के साथ आइटम वापस करें ।

मान लिया जाए objectsकि कहीं एक सरणी है ...

<tbody>
  { objects.map((obj, index) => <ObjectRow obj={ obj } key={ index }/> ) }
</tbody>

15

ES2015 Array.from मानचित्र फ़ंक्शन + कुंजी के साथ

यदि आपके पास कुछ नहीं है .map()तो तत्वों को दोहराने के Array.from()लिए mapफ़ंक्शन का उपयोग कर सकते हैं :

<tbody>
  {Array.from({ length: 5 }, (value, key) => <ObjectRow key={key} />)}
</tbody>

15

मैं इसका उपयोग करता हूं:

gridItems = this.state.applications.map(app =>
          <ApplicationItem key={app.Id} app={app } />
);

पुनश्च: कुंजी को कभी न भूलें या आपके पास बहुत सारी चेतावनियाँ होंगी!


या सरणी इंडेक्स का उपयोग करें यदि आपके आइटम में कोई .Idसंपत्ति नहीं है , जैसेitems.map( (item, index) => <Foo key={index}>{item}</Foo>
kontur

13

मैं उस दृष्टिकोण का पक्ष लेता हूं जहां प्रोग्रामिंग लॉजिक रिटर्न वैल्यू के बाहर होता है render। यह रखने में मदद करता है कि वास्तव में क्या करना आसान है।

तो मैं शायद कुछ ऐसा करूंगा:

import _ from 'lodash';

...

const TableBody = ({ objects }) => {
  const objectRows = objects.map(obj => <ObjectRow object={obj} />);      

  return <tbody>{objectRows}</tbody>;
} 

माना जाता है कि यह कोड की इतनी कम मात्रा है कि इसे इनलाइन करना ठीक काम कर सकता है।


वस्तुओं के माध्यम से पुनरावृत्ति के लिए लॉश मैप का बड़ा प्रशंसक। import { map } from 'lodash'अगर आप उन्हें जरूरत नहीं है, तो मैं सभी लिकैश कार्यों को आयात नहीं कर रहा हूं, इसलिए मैं इच्छुक हूं ।
स्ट्रेच0

इन दिनों हम भी दर्ज नक्शे की जरूरत नहीं है - बस सरणी पर सीधे मानचित्र।
एडम डोनाह्यू

हाँ, लेकिन आप es6 के साथ ऑब्जेक्ट के माध्यम से लूप नहीं कर सकते map(), केवल सरणियाँ। यही कारण है कि मैं कह रहा था कि एक वस्तु पर लूपिंग के लिए लॉश अच्छा है।
स्ट्रेच0

मुझे लगा कि आप objectsचीजों की एक सूची में हैं, मेरी गलती है।
एडम डोन्यू

12

आप निश्चित रूप से एक .map के साथ हल कर सकते हैं जैसा कि अन्य उत्तर द्वारा सुझाया गया है। यदि आप पहले से ही बेबल का उपयोग करते हैं, तो आप jsx-control-statement का उपयोग करने के बारे में सोच सकते हैं, उन्हें थोड़ी सी सेटिंग की आवश्यकता होती है, लेकिन मुझे लगता है कि यह पठनीयता के संदर्भ में (विशेष रूप से गैर-प्रतिक्रिया डेवलपर के लिए) लायक है। यदि आप एक लिंटर का उपयोग करते हैं, तो एस्लिंट-प्लगइन-जेएक्स-कंट्रोल-स्टेटमेंट भी हैं


12

आपका JSX कोड शुद्ध जावास्क्रिप्ट कोड में संकलित किया जाएगा, कोई भी टैग ReactElementवस्तुओं द्वारा प्रतिस्थापित किया जाएगा । जावास्क्रिप्ट में, आप उनके लौटे चर को इकट्ठा करने के लिए कई बार फ़ंक्शन को कॉल नहीं कर सकते।

यह गैरकानूनी है, फ़ंक्शन लौटे चर को संग्रहीत करने के लिए एक सरणी का उपयोग करने का एकमात्र तरीका है।

या आप इस स्थिति को संभालने के लिए जावास्क्रिप्ट ES5 के बाद सेArray.prototype.map उपलब्ध होने वाले उपयोग कर सकते हैं ।

हो सकता है कि हम एक नया JSX सिंटेक्स को फिर से बनाने के लिए अन्य संकलक लिख सकते हैं जैसे कि एंगुलर काng-repeat


12

यह कई तरीकों से किया जा सकता है।

  1. जैसा कि ऊपर सुझाव दिया गया है, returnसरणी में सभी तत्वों को संग्रहीत करने से पहले
  2. अंदर लूप return

    विधि 1

     let container =[];
        let arr = [1,2,3] //can be anything array, object 
    
        arr.forEach((val,index)=>{
          container.push(<div key={index}>
                         val
                         </div>)
            /** 
            * 1. All loop generated elements require a key 
            * 2. only one parent element can be placed in Array
            * e.g. container.push(<div key={index}>
                                        val
                                  </div>
                                  <div>
                                  this will throw error
                                  </div>  
                                )
            **/   
        });
        return (
          <div>
             <div>any things goes here</div>
             <div>{container}</div>
          </div>
        )

    विधि 2

       return(
         <div>
         <div>any things goes here</div>
         <div>
            {(()=>{
              let container =[];
              let arr = [1,2,3] //can be anything array, object 
              arr.forEach((val,index)=>{
                container.push(<div key={index}>
                               val
                               </div>)
                             });
                        return container;     
            })()}
    
         </div>
      </div>
    )

हाँ। अपने वर्तमान प्रोजेक्ट में, मैं HTML सेलेक्ट करने के लिए Array.prototype, forEach () पद्धति का उपयोग करके विधि 1 का उपयोग करता हूं, जो डेटाबेस से डेटा द्वारा पॉप्युलेट किया जाता है। हालाँकि, मैं अधिक संभावना उन्हें Array.prototype.map () विधि से बदलूंगा, क्योंकि मानचित्र विधि अधिक कॉम्पैक्ट (कम कोड) दिखती है।
लेक्स सॉफ्ट

10

यहाँ इसका एक सरल उपाय है।

var Object_rows=[];
for (var i=0; i < numrows; i++) {
    Object_rows.push(<ObjectRow/>)
} 
<tbody>
  {Object_rows}
</tbody>

कोई मैपिंग और जटिल कोड की आवश्यकता नहीं है। आपको केवल पंक्तियों को सरणी में धकेलने और इसे रेंडर करने के लिए मान वापस करने की आवश्यकता है।


Html सेलेक्ट एलिमेंट बनाते समय, इसी तरह की तकनीक वह थी जो सबसे पहले मेरे दिमाग में आई थी, इसलिए मैंने इसका इस्तेमाल किया, हालांकि मैं forEach () विधि का उपयोग करता हूं। लेकिन जब मैंने लिस्ट और कीज़ के विषयों पर रिएक्ट डॉक रीयर किया, तो मैंने पाया कि वे मैप () विधि का उपयोग करते हैं जैसा कि यहां कई उत्तरों द्वारा दिखाया गया है। इससे मुझे लगता है कि यह पसंदीदा तरीका है। मैं सहमत हूं, क्योंकि यह अधिक कॉम्पैक्ट (कम कोड) दिखता है।
लेक्स सॉफ्ट

9

चूंकि आप JSX कोड के अंदर जावास्क्रिप्ट सिंटैक्स लिख रहे हैं, इसलिए आपको अपनी जावास्क्रिप्ट को घुंघराले ब्रेस में लपेटने की आवश्यकता है।

row = () => {
   var rows = [];
   for (let i = 0; i<numrows; i++) {
       rows.push(<ObjectRow/>);
   }
   return rows;
}
<tbody>
{this.row()}  
</tbody>

9

यहाँ रिएक्ट डॉक्टर से एक नमूना है: बच्चों के रूप में जावास्क्रिप्ट एक्सप्रेशन

function Item(props) {
  return <li>{props.message}</li>;
}

function TodoList() {
  const todos = ['finish doc', 'submit pr', 'nag dan to review'];
  return (
    <ul>
      {todos.map((message) => <Item key={message} message={message} />)}
    </ul>
  );
}

आपके मामले के रूप में, मैं इस तरह से लिखने का सुझाव देता हूं:

function render() {
  return (
    <tbody>
      {numrows.map((roe, index) => <ObjectRow key={index} />)}
    </tbody>
  );
}

कृपया ध्यान दें कि कुंजी बहुत महत्वपूर्ण है, क्योंकि प्रतिक्रिया सरणी में डेटा को अलग करने के लिए कुंजी का उपयोग करती है।


9

मैं इसका उपयोग करता हूं

<tbody>
  { numrows ? (
     numrows.map(obj => { return <ObjectRow /> }) 
    ) : null
  }
</tbody>


8

बड़ा सवाल है।

जब मैं घटकों की एक निश्चित संख्या को जोड़ना चाहता हूं तो मैं एक सहायक फ़ंक्शन का उपयोग करता हूं।

एक फ़ंक्शन को परिभाषित करें जो JSX लौटाता है:

const myExample = () => {
    let myArray = []
    for(let i = 0; i<5;i++) {
        myArray.push(<MyComponent/>)
    }
    return myArray
}

//... in JSX

<tbody>
    {myExample()}
</tbody>

8

आप एक सेल्फ-इनवोकिंग फ़ंक्शन का भी उपयोग कर सकते हैं:

return <tbody>
           {(() => {
              let row = []
              for (var i = 0; i < numrows; i++) {
                  row.push(<ObjectRow key={i} />)
              }
              return row

           })()}
        </tbody>

रेंडर के अंदर अनाम फ़ंक्शंस का उपयोग करना प्रतिक्रिया में एक अच्छा अभ्यास नहीं माना जाता है, क्योंकि इन फ़ंक्शंस को प्रत्येक री-रेंडर पर फिर से बनाया या खारिज किया जाना चाहिए।
व्लातको वल्हेक

@VlatkoVlahek आप फंक्शन प्रॉप्स के साथ इसे गलत कर रहे हैं, जिससे प्रत्येक रेंडर चक्र को फिर से बनाया जा सकता है , जिससे बड़े पैमाने पर खराब प्रदर्शन हो सकता है । कहीं और अनाम फ़ंक्शन बनाना किसी भी महत्वपूर्ण तरीके से प्रदर्शन को प्रभावित नहीं करने वाला है।
एमिल बर्जरॉन

1
@EmileBergeron यह कुछ समय पहले हाहा था। मैं सहमत हूं कि अगर यह एक प्रोप के रूप में उपयोग नहीं किया जाता है, तो कोई अंतर नहीं है।
व्लातको व्लाक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.