[javascript] حلقة داخل React JSX


14 Answers

لست متأكدا ما إذا كان هذا سيعمل لموقفك ، ولكن في كثير من الأحيان map هي إجابة جيدة.

إذا كانت هذه هي شفرتك مع حلقة for:

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

يمكنك أن تكتبها هكذا مع map :

<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>
Question

أحاول أن أفعل شيئًا مثل ما يلي في React JSX (حيث يكون ObjectRow مكونًا منفصلاً):

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

أدرك وفهم سبب عدم صحة JSX ، نظرًا لأن JSX يعمل على تعيين المكالمات. ومع ذلك ، وأنا قادم من نموذج القالب وكوني جديدًا في JSX ، فأنا غير متأكد من كيفية تحقيق ما ورد أعلاه (إضافة مكون عدة مرات).




سيتم ترجمة شفرة ReactElement إلى شفرة جافا سكريبت خالصة ، وسيتم استبدال أية علامات ReactElement . في JavaScript ، لا يمكنك استدعاء دالة عدة مرات لتجميع المتغيرات التي تم إرجاعها.

إنه غير قانوني ، الطريقة الوحيدة هي استخدام صفيف لتخزين المتغيرات التي يتم إرجاعها.

أو يمكنك استخدام map والذي يتوفر منذ JavaScript ES5 للتعامل مع هذا الموقف.

ربما يمكننا أن نكتب مترجمًا آخر لإعادة إنشاء بنية JSX جديدة لتنفيذ وظيفة تكرار تمامًا مثل تكرار Angular في Angular .




هناك طرق متعددة للقيام بذلك. يتم تجميع JSX في النهاية إلى جافا سكريبت ، طالما أنك تكتب لغة جافا سكريبت صالحة ، فستكون جيدًا.

تهدف إجابتي إلى دمج جميع الطرق الرائعة التي تم تقديمها هنا:

إذا لم يكن لديك مجموعة من الكائنات ، ببساطة عدد الصفوف:

داخل كتلة return ، وإنشاء Array واستخدام Array.prototype.map :

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

خارج كتلة return ، ما عليك سوى استخدام JavaScript for-loop العادي:

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 ، ما عليك سوى استخدام JavaScript for-loop العادي:

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>
      {() => {
        let rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      }}
    </tbody>
  );
}



هناك عدة إجابات تشير إلى استخدام بيان map . في ما يلي مثال كامل باستخدام مكرر ضمن مكون FeatureList لسرد مكونات الميزة استنادًا إلى بنية بيانات 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>
); 

يمكنك عرض رمز FeatureList الكامل على GitHub. يتم سرد ميزات تركيبات هنا .




أنا استخدمها مثل

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



يمكنك فعل شيء مثل:

let foo = [1,undefined,3]
{ foo.map(e => !!e ? <Object /> : null )}



أعلم أن هذا خيط قديم ، ولكن قد ترغب في الخروج http://wix.github.io/react-templates/ ، مما يتيح لك استخدام قوالب نمط jsx في التفاعل ، مع بعض التوجيهات (مثل rt- كرر).

المثال الخاص بك ، إذا استخدمت قوالب تفاعل ، سيكون:

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



استخدام وظيفة Map Array هو طريقة شائعة جدًا لإجراء حلقة صفيف من العناصر وإنشاء مكونات وفقًا لها في React ، وهي طريقة رائعة للقيام بحلقة وهي طريقة فعالة ومرتبة لتنفيذ الحلقات في JSX ، وهي ليست الوحيدة طريقة للقيام بذلك ، ولكن الطريقة المفضلة.

لا تنس أيضًا وجود مفتاح فريد لكل تكرار كما هو مطلوب. تعمل وظيفة الخريطة على إنشاء فهارس فريدة من 0 ولكن لا يُنصح باستخدام الفهرس ، ولكن إذا كانت قيمتك فريدة أو إذا كان هناك مفتاح فريد ، فيمكنك استخدامها:

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

أيضًا عدد قليل من الخطوط من MDN إذا لم تكن معتادًا على وظيفة الخريطة في Array:

تستدعي الخريطة وظيفة معاودة الاتصال مرة واحدة لكل عنصر في صفيف ، بالترتيب ، وتبني مصفوفة جديدة من النتائج. يتم استدعاء رد الاتصال فقط من أجل فهارس الصفيف التي لها قيم معينة ، بما في ذلك غير محددة. لا يتم استدعاؤه لعناصر المصفوفة المفقودة (أي الفهارس التي لم يتم تعيينها أبداً ، والتي تم حذفها أو التي لم يتم تعيين قيمة لها).

يتم استدعاء معاودة الاتصال مع ثلاث وسائط: قيمة العنصر ، وفهرس العنصر ، وجسم صفيف يتم اجتيازه.

إذا تم توفير معلمة thisArg للخريطة ، فسيتم استخدام هذه القيمة كميزة معاودة الاتصال. بخلاف ذلك ، سيتم استخدام القيمة غير المعرفة كقيمة لهذه القيمة. يتم تحديد هذه القيمة التي يمكن ملاحظتها في النهاية عن طريق معاودة الاتصال وفقًا للقواعد المعتادة لتحديد ما تراه إحدى الوظائف.

لا تقوم الخريطة بتحوير المصفوفة التي يطلق عليها (على الرغم من أن معاودة الاتصال ، إذا تم استدعاءها ، قد تفعل ذلك).




ستحتاج إلى إضافة عناصر إلى مصفوفة وتجميع مجموعة العناصر.
يمكن أن يساعد هذا في تقليل الوقت المطلوب لإعادة عرض المكون.

إليك بعض التعليمات البرمجية التي قد تساعد في:

MyClass extends Component {
    constructor() {
        super(props)
        this.state = { elements: [] }
    }
    render() {
        return (<tbody>{this.state.elements}<tbody>)
    }
    add() {
        /*
         * The line below is a cheap way of adding to an array in the state.
         * 1) Add <tr> to this.state.elements
         * 2) Trigger a lifecycle update.
         */
        this.setState({
            elements: this.state.elements.concat([<tr key={elements.length}><td>Element</td></tr>])
        })
    }
}



ببساطة ، استخدم طريقة Array Map مع صيغة ES6:

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

لا تنس الملكية key .




انا استعمل هذا:

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

PD: أبدا ننسى المفتاح أو سيكون لديك الكثير من التحذيرات!




إذا اخترت تحويل هذا return () من طريقة العرض ، فسيكون من الأسهل استخدام طريقة map () . قم بتعيين صفيفك في صيغة JSX باستخدام وظيفة map () ، كما هو موضح أدناه ( يتم استخدام بنية ES6 ).

داخل المكون الرئيسي :

<tbody> { objectArray.map((object, index) => <ObjectRow key={index} object={object}>) } </tbody>

يرجى ملاحظة أن السمة key المضافة إلى مكون طفلك. إذا لم تقدم سمة أساسية ، يمكنك مشاهدة التحذير التالي على وحدة التحكم الخاصة بك.

تحذير: يجب أن يكون لكل طفل في مصفوفة أو أداة مساعدة دعامة "مفتاح" فريدة.

الآن في مكون ObjectRow يمكنك الوصول إلى الكائن من خصائصه.

داخل مكون ObjectRow

const { object } = this.props

أو

const object = this.props.object

هذا يجب أن يجلب لك الكائن الذي تم تمريره من المكون الرئيسي إلى object متغير في مكون ObjectRow . الآن يمكنك أن تبصق القيم في هذا الكائن وفقًا للغرض الخاص بك.

المراجع :

map

ECMA Script 6 أو ES6




ما عليك سوى استخدام .map() للتكرار من خلال المجموعة الخاصة بك <ObjectRow> عناصر <ObjectRow> مع props من كل التكرار.

افترض objects هي مجموعة في مكان ما ...

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



ES2015 Array.from مع وظيفة الخريطة + مفتاح

إذا لم يكن لديك أي شيء .map() يمكنك استخدام Array.from() مع mapFn لتكرار العناصر:

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



سؤال عظيم.

ما أقوم به عندما أريد إضافة عدد معين من المكونات هو استخدام وظيفة المساعد.

حدد وظيفة تقوم باعادة JSX:

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

//... in JSX

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





Related