Pertanyaan Loop di dalam React JSX


Saya mencoba melakukan sesuatu seperti berikut ini di React JSX (di mana ObjectRow adalah komponen terpisah):

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

Saya menyadari dan memahami mengapa ini tidak berlaku JSX, karena peta JSX berfungsi panggilan. Namun, berasal dari tanah template dan baru di BEJ, saya tidak yakin bagaimana saya akan mencapai hal di atas (menambahkan komponen beberapa kali).


736
2018-04-05 05:29


asal


Jawaban:


Anggap saja seperti Anda hanya memanggil fungsi JavaScript. Anda tidak bisa meletakkan for loop di dalam panggilan fungsi:

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

Tetapi Anda dapat membuat larik, lalu meneruskannya dalam:

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

Anda dapat menggunakan struktur dasarnya pada saat bekerja dengan 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>;

Kebetulan, contoh JavaScript saya hampir persis apa yang menjadi contoh JSX berubah menjadi. Bermain-main dengan Babel REPL untuk merasakan bagaimana JSX bekerja.


754
2018-04-05 05:39



Tidak yakin apakah ini akan bekerja untuk situasi Anda, tetapi sering peta adalah jawaban yang bagus.

Jika ini adalah kode Anda dengan for loop:

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

Anda bisa menulisnya seperti ini peta:

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

Sintaks ES6:

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

639
2018-04-05 05:46



Jika Anda belum memiliki array map() seperti jawaban @ FakeRainBrigand, dan ingin inline ini sehingga tata letak sumber sesuai dengan output lebih dekat daripada jawaban @ SophieAlpert:

Dengan sintaks ES2015 (ES6) (fungsi spread dan panah)

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

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

Re: transpiling dengan Babel, itu halaman peringatan mengatakan itu Array.from diperlukan untuk penyebaran, tetapi saat ini (v5.8.23) yang tampaknya tidak menjadi kasus ketika menyebarkan yang sebenarnya Array. Saya punya masalah dokumentasi terbuka untuk mengklarifikasi itu. Tetapi gunakan dengan resiko atau polyfill Anda sendiri.

Vanilla ES5

Array.apply

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

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

Kombinasi teknik dari jawaban lainnya

Pertahankan tata letak sumber yang sesuai dengan output, tetapi buat bagian inline lebih ringkas:

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

Dengan sintaks ES2015 & Array metode

Dengan Array.prototype.fill Anda dapat melakukan ini sebagai alternatif untuk menggunakan spread seperti yang digambarkan di atas:

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

(Saya pikir Anda benar-benar dapat menghilangkan argumen apa pun fill(), tapi saya tidak 100% tentang itu.) Terima kasih kepada @FakeRainBrigand untuk mengoreksi kesalahan saya dalam versi sebelumnya dari fill() solusi (lihat revisi).

key

Dalam semua kasus itu key attr mengurangi peringatan dengan pembangunan, tetapi tidak dapat diakses oleh anak. Anda dapat melewati attr tambahan jika Anda ingin indeks tersedia di anak. Lihat Daftar dan Tombol untuk diskusi.


317
2018-04-14 14:08



Cukup menggunakan peta  Array metode dengan sintaks ES6:

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

Jangan lupakan itu key milik.


52
2017-10-30 04:35



Menggunakan Peta Array fungsi adalah cara yang sangat umum untuk mengulang melalui suatu Array elemen dan membuat komponen sesuai mereka ReaksiIni adalah cara yang bagus untuk melakukan loop yang cukup efisien dan rapi untuk melakukan loop Anda JSX, Itu tidak satu - satunya cara untuk melakukannya, tetapi cara yang disukai. 

Juga, jangan lupa memiliki Kunci unik untuk setiap iterasi sesuai kebutuhan. Fungsi peta membuat indeks unik dari 0 tetapi tidak disarankan menggunakan indeks tetapi jika nilai Anda unik atau jika ada kunci unik, Anda dapat menggunakannya:

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

Juga beberapa baris dari MDN jika Anda tidak akrab dengan fungsi peta di Array:

map memanggil fungsi callback yang disediakan satu kali untuk setiap elemen dalam suatu   larik, dalam urutan, dan membuat larik baru dari hasil. panggilan balik   hanya dipanggil untuk indeks array yang telah menetapkan nilai,   termasuk tidak terdefinisi. Itu tidak disebut untuk elemen yang hilang   array (yaitu, indeks yang belum pernah diatur, yang telah   dihapus atau yang tidak pernah diberi nilai).

panggilan balik dipanggil dengan tiga argumen: nilai elemen,   indeks elemen, dan objek Array sedang dilalui.

Jika parameterArg ini disediakan untuk dipetakan, ini akan digunakan sebagai   panggil nilai ini. Jika tidak, nilai tidak terdefinisi akan digunakan sebagai   nilai ini. Nilai ini akhirnya dapat diobservasi oleh callback tersebut   ditentukan sesuai dengan aturan biasa untuk menentukan hal ini dilihat   oleh suatu fungsi.

peta tidak bermutasi array yang disebut (meskipun   panggilan balik, jika dipanggil, dapat dilakukan).


41
2018-05-16 13:37



Jika Anda sudah menggunakan lodash, itu _.times fungsi berguna.

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

33
2017-10-05 05:35



Anda juga dapat mengekstrak di luar blok pengembalian:

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

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

25
2018-01-04 05:53



Saya tahu ini adalah thread lama, tetapi Anda mungkin ingin checkout http://wix.github.io/react-templates/, yang memungkinkan Anda menggunakan templat bergaya jsx dalam bereaksi, dengan beberapa arahan (seperti rt-repeat).

Contoh Anda, jika Anda menggunakan template-reaksi, adalah:

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

20
2018-02-02 19:35



jika numrows adalah array, dan itu sangat sederhana.

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

Tipe data array dalam React sangat baik, array dapat kembali array baru, dan mendukung filter, mengurangi dll.


15
2018-01-11 09:49



Ada beberapa jawaban yang menunjuk untuk menggunakan map pernyataan. Berikut ini contoh lengkap menggunakan iterator di dalam FeatureList komponen ke daftar Fitur komponen berdasarkan struktur data JSON yang disebut fitur.

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

Anda dapat melihat yang lengkap Kode FeatureList di GitHub. Itu perlengkapan fitur tercantum di sini.


15
2018-05-29 20:59