Merender Komponen React dari Array of Objects

99

Saya memiliki beberapa data yang disebut stasiun yang merupakan larik yang berisi objek.

stations : [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
]

Saya ingin merender komponen ui untuk setiap posisi array. Sejauh ini saya bisa menulis

 var stationsArr = []
 for (var i = 0; i < this.data.stations.length; i++) {
     stationsArr.push(
         <div className="station">
             {this.data}
         </div>
     )
 }

Dan kemudian render

render(){
 return (
   {stationsArr}
 )
}

Masalahnya adalah saya mendapatkan semua data yang dicetak. Saya hanya ingin menunjukkan kunci seperti {this.data.call}tetapi tidak mencetak apa-apa.

Bagaimana cara melakukan loop melalui data ini dan mengembalikan elemen UI baru untuk setiap posisi array?

thatgibbyguy
sumber
Saya bisa saja salah tetapi saya pikir Anda perlu menggunakan stationsArralih-alih stationsdi dalam renderfungsi.
Tahir Ahmed

Jawaban:

151

Anda dapat memetakan daftar stasiun ke ReactElements.

Dengan React> = 16, dimungkinkan untuk mengembalikan beberapa elemen dari komponen yang sama tanpa memerlukan pembungkus elemen html tambahan. Sejak 16.2, ada sintaks baru <> untuk membuat fragmen. Jika ini tidak berhasil atau tidak didukung oleh IDE Anda, Anda dapat menggunakannya <React.Fragment>. Antara 16.0 dan 16.2, Anda dapat menggunakan polyfill yang sangat sederhana untuk fragmen.

Coba berikut ini

// Modern syntax >= React 16.2.0
const Test = ({stations}) => (
  <>
    {stations.map(station => (
      <div className="station" key={station.call}>{station.call}</div>
    ))}
  </>
); 

// Modern syntax < React 16.2.0
// You need to wrap in an extra element like div here

const Test = ({stations}) => (
  <div>
    {stations.map(station => (
      <div className="station" key={station.call}>{station.call}</div>
    ))}
  </div>
); 

// old syntax
var Test = React.createClass({
    render: function() {
        var stationComponents = this.props.stations.map(function(station) {
            return <div className="station" key={station.call}>{station.call}</div>;
        });
        return <div>{stationComponents}</div>;
    }
});

var stations = [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
]; 

ReactDOM.render(
  <div>
    <Test stations={stations} />
  </div>,
  document.getElementById('container')
);

Jangan lupakan keyatributnya!

https://jsfiddle.net/69z2wepo/14377/

Sebastien Lorber
sumber
@thatgibbyguy: Oh ya! itu bisa jadi jawaban yang benar. Perlu ada pembungkus di sekitar komponen anak Anda. renderFungsi Anda harus mengembalikan satu elemen.
Tahir Ahmed
Apa alasan untuk menyarankan atribut kunci untuk setiap elemen stasiun? Yang saya tanyakan adalah, perubahan apa yang akan terjadi jika tidak diperlukan sekarang?
thatgibbyguy
4
@thatgibbyguy dalam hal ini tidak membawa banyak keuntungan. Dalam contoh yang lebih maju, ini memungkinkan untuk memiliki kinerja rendering yang lebih baik karena React dapat dengan mudah mengetahui jika node yang ada telah dipindahkan ke tempat lain dalam array stasiun, sehingga menghindari untuk menghancurkan dan membuat ulang node dom yang ada (dan juga menjaga node dom tetap terpasang) . Ada di doc react: facebook.github.io/react/docs/reconciliation.html#keys
Sebastien Lorber
Sedikit keluar dari topik tetapi saya tidak yakin bagaimana membuat kueri untuk menanyakan hal ini. Saat menggunakan sintaks ES6 dalam contoh Anda di atas, bagaimana cara meneruskan indeks dari peta? IOW, bagaimana saya bisa mengetahui jika saya berada di node terakhir dari array? Saya mencoba membungkusnya dengan paren dan sepertinya tidak berhasil.
Lane Goolsby
@ElHomb stations.map((station,index) => { })bekerja dengan baik untuk saya
Sebastien Lorber
46

Saya punya jawaban yang mungkin tidak terlalu membingungkan untuk pemula seperti saya. Anda bisa menggunakan mapmetode render komponen.

render () {
   return (
       <div>
           {stations.map(station => <div key={station}> {station} </div>)} 
       </div>
   );
}
Thomas Valadez
sumber
11
Ini membutuhkan keyprop reactjs.org/docs/lists-and-keys.html#keys
David Barratt
1
Terkadang ini jauh lebih membantu. :)
ferit
6

this.data mungkin berisi semua data, jadi Anda perlu melakukan sesuatu seperti ini:

var stations = [];
var stationData = this.data.stations;

for (var i = 0; i < stationData.length; i++) {
    stations.push(
        <div key={stationData[i].call} className="station">
            Call: {stationData[i].call}, Freq: {stationData[i].frequency}
        </div>
    )
}

render() {
  return (
    <div className="stations">{stations}</div>
  )
}

Atau Anda dapat menggunakan mapfungsi panah dan jika Anda menggunakan ES6:

const stations = this.data.stations.map(station =>
    <div key={station.call} className="station">
      Call: {station.call}, Freq: {station.frequency}
    </div>
);
Dominic
sumber
2
Ini tidak akan berfungsi dalam Versi React saat ini, Anda tidak dapat mengembalikan array.
Aftab Naveed
@AftabNaveed terima kasih saya telah memperbaruinya, render harus mengembalikan satu elemen tetapi valid untuk memiliki serangkaian elemen di dalamnya
Dominic
Seperti yang dikatakan @AftabNaveed, jika bereaksi versi <16, Anda harus menggunakan di atas, jika tidak, Anda dapat return stations;( codepen.io/pawelgrzybek/pen/WZEKWj )
Chicken Soup
1

Ada beberapa cara yang bisa digunakan.

const stations = [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
];
const callList = stations.map(({call}) => call)

Solusi 1

<p>{callList.join(', ')}</p>

Solusi 2

<ol>    
  { callList && callList.map(item => <li>{item}</li>) }
</ol>

Edit jenis-antonelli-z8372

Tentu ada cara lain juga tersedia.

Mo.
sumber