React JSX内のループ


1278

Reactで次のようなことを実行しようとしていますJSX(ObjectRowは別のコンポーネントです)。

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

関数呼び出しにマップしているJSXので、これが有効ではない理由を理解しましたJSX。しかし、テンプレートランドから来てJSX、に新しいので、上記をどのように達成するか(コンポーネントを複数回追加する)はわかりません。


38
JSXでは、JavaScript構文の前後に{}タグが必要であることに注意してください。これはfacebook.github.io/react/docs/…を助けるかもしれません。
Isaiah Grey

30
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
OverCoder 2017年


@OverCoderなぜ全体のリターンを{}タグに入れるのでしょうか=> return <h1> {todo.title} </ h1>ではありませんか?
pravin poudel

1
@pravinpoudel実際にはその答えは古く、もっとlet todos = this.props.todos.map(t => <h1>{t.title}</h1>):)のようです
OverCoder

回答:


1205

JavaScript関数を呼び出すようなものだと考えてください。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>;

ちなみに、私のJavaScriptの例は、JSXの例が変換するものとほぼ同じです。遊んバベルREPL JSXがどのように動作するかの感触を得るために。


3
この例はjsxコンパイラーでコンパイルされていないように見えるため、コンパイラーが変更された可能性がありますが、以下のFakeRainBrigandの回答のようにマップを使用すると、正しくコンパイルされるようです。
rav

9
最後の例が最新のJSXコンパイラで正しくコンパイルされることをお約束します。
ソフィーアルパート2014

3
これはうまくいきます。FakeRainBrigandの答えは単純な配列反復に有効ですが、この答えは、使用できないシナリオmap(たとえば、変数にコレクションが格納されていないなど)には必須です。
ケルビン

52
Reactはdomを効率的に更新する必要があります。この場合、親はkey各子にを割り当てる必要があります。REF:facebook.github.io/react/docs/...
qsun

7
これは機能する例ですが、keyプロパティやReactコードベースでは実際には使用されていないコードスタイルなど、いくつかの重要なビットがありません。この回答stackoverflow.com/questions/22876978/loop-inside-react-jsx/…を正しいものと見なしてください。
okonetchnikov

866

これがあなたの状況でうまくいくかどうかはわかりませんが、しばしばマップが良い答えです。

これがforループを使用したコードの場合:

<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
iterateeが配列である場合、マップはより意味があります。数値の場合、forループが適切です。
Code Whisperer、2015

26
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>ReactifyのES6サポートまたはBabelを使用します。
Distortum 2015

3
+1。私はこれをul(順不同リスト)でも使用しています。<ul> {objects.map((object:string,i:number)=>{ return <li>{object}</li> })} </ul>TypeScriptを使用
Roberto C Navarro

5
これは素晴らしいですが、私が使用することのためにあなたは...オブジェクトの上にマッピングすることはできませんfor..in
デイモン

4
Object.keysを使用する場合、キーの順序は任意であることを覚えておいてください。キーの順序を個別に保存することも、必要に応じてオブジェクトリテラルの順序を保存することもうまくいくことがわかりました。これにより、次のようなコードを記述できますthis.props.order.map((k)=><ObjectRow key={k} {...this.props.items[k]} />)
tgrrr

443

map()@FakeRainBrigandの答えが好きな配列がまだない場合、これをインライン化して、ソースレイアウトが@SophieAlpertの答えよりも近い出力に対応するようにするには、次のようにします。

ES2015(ES6)構文(スプレッドおよび矢印関数)

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

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

Re:Babelを使ったトランスパイル、その警告のページでは、これArray.fromは拡散に必要であると述べていますが、現時点(v5.8.23)では、実際の拡散ではそうではないようですArrayドキュメントに問題がありますを明確にするために開いています。ただし、自己責任またはポリフィルで使用してください。

バニラES5

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

すべての場合において、keyattrは開発ビルドでの警告を緩和しますが、子ではアクセスできません。子で使用可能なインデックスが必要な場合は、追加のattrを渡すことができます。説明については、リストとキーを参照してください。


2
どうyieldですか?ジェネレーターがある場合、要素を中間配列にプッシュするのはちょっと醜いです。彼らは働きますか?
mpen

2
@Markジェネレータが実際にここで適用できるかどうかはわかりません。JSXのコンテキストにおけるこのための重要な点は、配列を返す式です。したがって、何らかの方法でジェネレータを使用する場合は、おそらくそれをとにかく拡散し、ES2015ベースのソリューションよりも詳細になる可能性があります。
JMM 2015

2
これはどのように冗長ですか?また、JSXが配列だけでなく反復可能なものを受け入れないのはなぜですか?
mpen

2
@Markそれは確かに、私が使用した(ES5)IIFEの例よりも冗長ではありませんが、[...Array(x)].map(() => <El />))バージョンよりもかなり冗長です。再:2番目の質問、それは素晴らしい点です。それを妨げるJSXについては何もないように見えるので、それはReactまたは変換されたJSXの別のコンシューマーが子の引数をどのように処理するかに依存します。あなたは知っていますか?それは興味深い質問です。
JMM 2015

3
@corysimmonsクール、の情報をありがとうfill()。私がそのことをためらった理由は、ES仕様でパラメーターのオプション性がどのように示されているかについての質問であることを覚えています(いつか検討する必要があります)。コンマは、配列要素(この場合は最初の要素)を除外する方法にすぎません。インデックスを配列の1..lengthから広げたい場合は、これを行うことができます(省略された要素が配列の長さに寄与するだけなので、対応するプロパティがあります)。
JMM

85

ES6構文でmap Arrayメソッドを使用するだけです。

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

keyプロパティを忘れないでください。


idの代わりにランダムな「Math.random()」キーを追加します。子の内部でsetStateを実行すると正常に機能しません。理由は何かありますか?
Oliver D

82

使用するアレイマップ機能ををループに非常に一般的な方法ですアレイでそれらをに従って要素のとコンポーネントを作成REACT、これは中にあなたのループを行うにはかなり効率的であるループと整頓方法行うための素晴らしい方法ですJSXを、それはだないだけそれを行う方法です が、好ましい方法です。

また、必要に応じて、反復ごとに一意のキーを設定することを忘れないでください。map関数は0から一意のインデックスを作成しますが、生成されたインデックスを使用することはお勧めしませんが、値が一意の場合、または一意のキーがある場合は、それらを使用できます。

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

また、配列のマップ機能に慣れていない場合、MDNからの数行:

mapは、配列内の各要素に対して提供されたコールバック関数を順番に1回呼び出し、その結果から新しい配列を作成します。コールバックは、未定義を含む、値が割り当てられている配列のインデックスに対してのみ呼び出されます。配列の欠落している要素(つまり、設定されていないインデックス、削除されているインデックス、または値が割り当てられていないインデックス)に対しては呼び出されません。

コールバックは3つの引数で呼び出されます:要素の値、要素のインデックス、およびトラバースされるArrayオブジェクト。

thisArgパラメータがマップに提供されている場合、コールバックのthis値として使用されます。それ以外の場合、未定義の値がこの値として使用されます。コールバックによって最終的に観察可能なこの値は、関数から見たこれを決定するための通常のルールに従って決定されます。

mapは、それが呼び出された配列を変更しません(ただし、コールバックが呼び出された場合、変更される場合があります)。


Array#map非同期ではありません!
philraj 2017

52

すでにlodashを使用している場合、この_.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
lodashなどのライブラリを含めない場合、ここではArray.prototype.mapが優れたオプションになる可能性があります。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Isaiah Grey

1
@IsaiahGreyすでに配列を取得している場合のみ。時には、何回か繰り返したいだけです。
mpen

1
もちろん!実際のデータに応じて、多くの異なるアプローチがあります。多くの場合、私たちの開発プロセスでは、モデル化された場合のデータが原因で、マップを適合させることができました。lodashを使用した素晴らしい例!ところで、プロパティ初期化構文を使用して、メソッドをコンポーネントにバインドしていますか?
Isaiah Grey

4
@IsaiahGrey ES6 メソッド定義
mpen

41

returnブロックの外で抽出することもできます。

render: function() {
    var rows = [];
    for (var i = 0; i < numrows; i++) {
        rows.push(<ObjectRow key={i}/>);
    } 

    return (<tbody>{rows}</tbody>);
}

34

これは古いスレッドであることはわかっていますが、チェックアウトすることをお勧めします Reactテンプレート、いくつかのディレクティブ(rt-repeatなど)を使用して、jsxスタイルのテンプレートをreactで使用できるすることをお勧めします。

あなたの例は、react-templatesを使用した場合、次のようになります。

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

単純なJavaScriptが問題を解決するためにさまざまな種類のforループまたはArray.prototype.mapメソッドのいずれかのソリューションをすでに提供しているのに、なぜ追加のライブラリを使用するのですか?私自身は、現在のプロジェクトで正常に動作する両方の単純なJavaScriptの方法をすでに使用しています。可能な限り簡単なJavaScriptの方法を使用する習慣があると、JavaScriptのスキルが向上します。React-Routerを使用したルーティングなど、特定の問題の解決策を見つけることが難しいと思われる場合にのみ、追加のライブラリーを使用します。
Lex Soft

27

これを行うにはいくつかの方法があります。JSXは最終的にJavaScriptにコンパイルされるため、有効なJavaScriptを作成している限り、問題はありません。

私の答えは、すでにここに提示されているすべての素晴らしい方法を統合することを目指しています。

オブジェクトの配列がない場合は、単純に行数:

returnブロック内で、作成Arrayおよび使用Array.prototype.map

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

returnブロックの外では、通常のJavaScriptのforループを使用するだけです。

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ループを使用するだけです。

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
素晴らしい答え:さまざまなテクニック、すべてが同様のタスクを実行するさまざまな方法のおかげで、JavaScriptの力を示すプレーンJavaScriptのみを使用します。
Lex Soft

24

numrowsが配列の場合、それは非常に単純です。

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

Reactの配列データ型は非常に優れており、配列は新しい配列をサポートし、フィルターのサポート、削減などを行うことができます。


これはキーを使用しないため、適切な回答ではありません。
kojow7 2017

21

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>
); 

GitHubで完全なFeatureListコードを表示できます。フィクスチャがここにリストされています


JSONデータを処理するとき(フェッチAPIを使用してデータベースからデータを取得するときなど)は、Array.prototype.mapメソッドの使用に依存しています。これは、そのための便利で実績のある方法です。
Lex Soft

17

時間とリターンの数のループに、あなたはの助けを借りて、それを達成することができますfromし、map

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

どこ i = number of times


レンダリングされたコンポーネントに一意のキーIDを割り当てる場合React.Children.toArrayは、Reactドキュメントで提案されているとおりに使用できます。

React.Children.toArray

子の不透明なデータ構造を、各子に割り当てられたキーを持つフラット配列として返します。レンダーメソッドで子のコレクションを操作する場合、特にthis.props.childrenを渡す前に並べ替えまたはスライスする場合に役立ちます。

注意:

React.Children.toArray()子のリストをフラット化するときに、ネストされた配列のセマンティクスを保持するようにキーを変更します。つまり、toArrayは返された配列の各キーにプレフィックスを付けて、各要素のキーのスコープがそれを含む入力配列に設定されるようにします。

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

17

あなたはこの内部変換するために選択した場合のリターン()レンダリング方法を、最も簡単なオプションが使用されるだろうマップ()メソッドを。次に示すように、map()関数を使用して配列をJSX構文にマッピングします(ES6構文が使用されます)。


親コンポーネント内

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

key子コンポーネントに追加された属性に注意してください。キー属性を指定しなかった場合、コンソールに次の警告が表示されます。

警告:配列または反復子の各子には、一意の「キー」プロップが必要です。

注:よくある間違いの1つはindex、反復時にキーとして使用することindexです。要素をキーとして使用することはアンチパターンであり、詳細についてはこちらをご覧ください。要するに、それはだ場合、NOT静的リスト使用することはありませんindexキーとして。


ObjectRowでコンポーネントには、その性質からオブジェクトにアクセスすることができます。

ObjectRowコンポーネントの内部

const { object } = this.props

または

const object = this.props.object

これにより、親コンポーネントからObjectRowコンポーネントの変数objectに渡したオブジェクトがフェッチされます。これで、目的に応じてそのオブジェクトの値を吐き出すことができます。


参照:

JavaScriptのmap()メソッド

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>

map(item)の後の{}を取り除く必要があるかもしれません。
Ian

15

ES2015 / Babelの可能性は、ジェネレーター関数を使用してJSXの配列を作成することです。

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 } />
);

PS:キーを忘れないでください。そうしないと、多くの警告が表示されます。


あなたの項目が持っていない場合、または配列のインデックスを使用する.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'あなたがそれらを必要としないのであれば、あなたはすべてのlodash関数をインポートしないので、私は傾向があります。
Stretch0

最近では、lodashマップも必要ありません。配列を直接マップするだけです。
アダムドナヒュー

ええ、でもes6 map()ではオブジェクトをループできません。配列だけです。lodashはオブジェクトをループするのに適していると私は言っていました。
Stretch0 2018年

私はあなたobjectsが物事のリストのように、私の間違いを意味すると思った。
アダムドナヒュー


12

JSXコードは純粋なJavaScriptコードにコンパイルされ、タグはすべてReactElementオブジェクトに置き換えられます。JavaScriptでは、返された変数を収集するために関数を複数回呼び出すことはできません。

不正です。唯一の方法は、配列を使用して関数から返された変数を格納することです。

または、JavaScript ES5以降Array.prototype.mapで使用可能なwhichを使用してこの状況を処理できます。

たぶん、Angularのng-repeatように、繰り返し機能を実装するために新しいJSX構文を再作成する他のコンパイラーを書くことができます。


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

うん。現在のプロジェクトでは、方法1を使用します。つまり、Array.prototype、forEach()メソッドを使用して、データベースからのデータが入力されるHTML選択要素を作成します。ただし、mapメソッドがよりコンパクトに見える(コードが少ない)ため、これらをArray.prototype.map()メソッドで置き換える可能性が高くなります。
Lex Soft

10

これに対する簡単な解決策を次に示します。

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

マッピングや複雑なコードは必要ありません。行を配列にプッシュし、値を返してレンダリングするだけです。


HTMLのselect要素を作成するときに、この類似の手法が最初に頭に浮かんだので、forEach()メソッドを使用しましたが、それを使用しました。しかし、リストとキーのトピックに関するReactドキュメントをもう一度読んだとき、ここでいくつかの回答で示されているように、map()メソッドを使用していることがわかりました。これは私がそれが好ましい方法だと思います。コンパクトに見える(コードが少ない)ので、同意します。
Lex Soft

9

JSXコード内でJavascript構文を記述しているため、Javascriptを中括弧で囲む必要があります。

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

9

これは、React docのサンプルです:子としてのJavaScript式

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>
  );
}

Reactはキーを使用して配列内のデータを区別するため、キーが非常に重要であることに注意してください。


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>

これらの関数は再レンダリングするたびに再作成または破棄する必要があるため、render内で匿名関数を使用することは、reactの良い習慣とは見なされません。
Vlatko Vlahek 2017

@VlatkoVlahekレンダリングサイクルごとに再作成される関数の小道具と誤解しているため、大規模なパフォーマンスの低下につながる可能性があります。他の場所で無名関数を作成しても、パフォーマンスに大きな影響はありません。
エミールベルジェロン

1
@EmileBergeronこれはちょっと前の話です。これを小道具として使用しない場合、違いはありません。
Vlatko Vlahek
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.