Saya sedang membangun komponen Bereaksi yang menerima sumber data JSON dan membuat tabel yang bisa diurutkan.
Setiap baris data dinamis memiliki kunci unik yang ditetapkan untuknya tetapi saya masih mendapatkan kesalahan:
Setiap anak dalam array harus memiliki prop "kunci" yang unik.
Periksa metode render dari TableComponent.
TableComponent
Metode render saya kembali:
<table>
<thead key="thead">
<TableHeader columns={columnNames}/>
</thead>
<tbody key="tbody">
{ rows }
</tbody>
</table>
The TableHeader
komponen satu baris dan juga memiliki kunci yang unik yang ditugaskan untuk itu.
Setiap row
in rows
dibangun dari komponen dengan kunci unik:
<TableRowItem key={item.id} data={item} columns={columnNames}/>
Dan TableRowItem
tampilannya seperti ini:
var TableRowItem = React.createClass({
render: function() {
var td = function() {
return this.props.columns.map(function(c) {
return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
}, this);
}.bind(this);
return (
<tr>{ td(this.props.item) }</tr>
)
}
});
Apa yang menyebabkan kesalahan kunci prop unik?
javascript
reactjs
Brett DeWoody
sumber
sumber
key
properti unik . Ini akan membantu ReactJS untuk menemukan referensi ke simpul DOM yang sesuai dan memperbarui konten hanya di dalam mark-up tetapi tidak merender ulang seluruh tabel / baris.rows
array atau lebih disukai jsfiddle? Anda tidak perlukey
propertithead
dantbody
omong-omong.Jawaban:
Anda harus menambahkan kunci untuk setiap anak dan setiap elemen di dalam anak-anak .
Dengan cara ini Bereaksi dapat menangani perubahan DOM minimal.
Dalam kode Anda, masing-masing
<TableRowItem key={item.id} data={item} columns={columnNames}/>
- berusaha membuat beberapa anak di dalamnya tanpa kunci.Lihat contoh ini .
Coba hapus
key={i}
dari<b></b>
elemen di dalam div (dan periksa konsol).Dalam sampel, jika kita tidak memberikan kunci untuk
<b>
elemen dan kami ingin memperbarui hanya satuobject.city
, Bereaksi kebutuhan untuk re-render seluruh baris vs hanya elemen.Ini kodenya:
Jawaban yang diposting oleh @Chris di bagian bawah jauh lebih detail daripada jawaban ini. Silakan lihat di https://stackoverflow.com/a/43892905/2325522
Bereaksi dokumentasi tentang pentingnya kunci dalam rekonsiliasi: Kunci
sumber
key
nilai untuk prop adalah unik untuk setiap item dan Anda meletakkankey
prop pada komponen yang paling dekat dengan batas array. Sebagai contoh, dalam React Native, pertama saya mencoba meletakkankey
prop ke<Text>
komponen. Namun saya harus meletakkannya di<View>
komponen yang merupakan induk dari<Text>
. jika Array == [(Lihat> Teks), (Lihat> Teks)] Anda harus meletakkannya ke Lihat. Bukan Teks.Hati-hati saat mengulangi array !!
Ini adalah kesalahpahaman umum bahwa menggunakan indeks elemen dalam array adalah cara yang dapat diterima untuk menekan kesalahan yang mungkin Anda kenal:
Namun, dalam banyak kasus tidak! Ini adalah anti-pola yang dalam beberapa situasi dapat menyebabkan perilaku yang tidak diinginkan .
Memahami
key
propBereaksi menggunakan
key
prop untuk memahami hubungan Elemen-ke-DOM elemen, yang kemudian digunakan untuk proses rekonsiliasi . Oleh karena itu sangat penting bahwa kunci selalu tetap unik , jika tidak ada kesempatan bagus Bereaksi akan mencampur unsur-unsur dan bermutasi yang salah. Penting juga bahwa tombol-tombol ini tetap statis di seluruh rendering ulang untuk mempertahankan kinerja terbaik.Yang sedang berkata, seseorang tidak selalu perlu menerapkan di atas, asalkan diketahui bahwa array benar-benar statis. Namun, menerapkan praktik terbaik dianjurkan sedapat mungkin.
Pengembang Bereaksi mengatakan dalam masalah GitHub ini :
Singkatnya, a
key
seharusnya:Menggunakan
key
propSesuai dengan penjelasan di atas, pelajari sampel-sampel berikut dengan cermat dan cobalah untuk mengimplementasikan, bila mungkin, pendekatan yang direkomendasikan.
Buruk (Berpotensi)
Ini bisa dibilang kesalahan paling umum yang terlihat ketika iterasi di atas array di Bereaksi. Pendekatan ini secara teknis tidak "salah" , itu hanya ... "berbahaya" jika Anda tidak tahu apa yang Anda lakukan. Jika Anda melakukan iterasi melalui array statis maka ini adalah pendekatan yang benar-benar valid (mis. Array tautan dalam menu navigasi Anda). Namun, jika Anda menambahkan, menghapus, memesan kembali, atau memfilter item, maka Anda harus berhati-hati. Lihatlah penjelasan terperinci ini dalam dokumentasi resmi.
Tampilkan cuplikan kode
Dalam cuplikan ini kami menggunakan array non-statis dan kami tidak membatasi diri untuk menggunakannya sebagai tumpukan. Ini adalah pendekatan yang tidak aman (Anda akan melihat alasannya). Perhatikan bagaimana saat kita menambahkan item ke awal array (pada dasarnya unshift), nilai untuk masing-masing
<input>
tetap di tempatnya. Mengapa? Karenakey
tidak mengidentifikasi setiap item secara unik.Dengan kata lain, pada awalnya
Item 1
sudahkey={0}
. Ketika kami menambahkan item kedua, item teratas menjadiItem 2
, diikuti olehItem 1
sebagai item kedua. Namun, sekarangItem 1
sudahkey={1}
dan tidakkey={0}
lagi. Sebaliknya,Item 2
sekarang sudahkey={0}
!!Karena itu, React berpendapat bahwa
<input>
unsur - unsurnya tidak berubah, karenaItem
kunci dengan0
selalu ada di atas!Jadi mengapa pendekatan ini saja terkadang buruk?
Pendekatan ini hanya berisiko jika array entah bagaimana difilter, disusun ulang, atau item ditambahkan / dihapus. Jika selalu statis, maka sangat aman untuk digunakan. Misalnya, menu navigasi suka
["Home", "Products", "Contact us"]
dapat dengan aman diulangi dengan metode ini karena Anda mungkin tidak akan pernah menambahkan tautan baru atau mengatur ulang.Singkatnya, inilah saatnya Anda dapat menggunakan indeks dengan aman sebagai
key
:Seandainya kami, dalam cuplikan di atas, mendorong item yang ditambahkan ke akhir array, urutan untuk setiap item yang ada akan selalu benar.
Sangat buruk
Meskipun pendekatan ini mungkin akan menjamin keunikan kunci, itu akan selalu memaksa bereaksi untuk membuat kembali setiap item dalam daftar, bahkan ketika ini tidak diperlukan. Ini solusi yang sangat buruk karena sangat memengaruhi kinerja. Belum lagi bahwa seseorang tidak dapat mengecualikan kemungkinan tabrakan kunci dalam acara yang
Math.random()
menghasilkan angka yang sama dua kali.Baik sekali
Ini bisa dibilang pendekatan terbaik karena menggunakan properti yang unik untuk setiap item dalam dataset. Misalnya, jika
rows
berisi data yang diambil dari basis data, seseorang dapat menggunakan Kunci Utama tabel ( yang biasanya merupakan nomor yang bertambah secara otomatis ).Baik
Ini juga merupakan pendekatan yang baik. Jika dataset Anda tidak berisi data apa pun yang menjamin keunikan ( misalnya, array nomor sewenang-wenang ), ada kemungkinan tabrakan kunci. Dalam kasus seperti itu, yang terbaik adalah secara manual menghasilkan pengidentifikasi unik untuk setiap item dalam dataset sebelum mengulanginya. Lebih disukai ketika memasang komponen atau ketika dataset diterima ( misalnya dari
props
atau dari panggilan API async ), untuk melakukan ini hanya sekali , dan tidak setiap kali komponen dirender ulang. Sudah ada beberapa perpustakaan di luar sana yang dapat memberikan Anda kunci tersebut. Berikut ini salah satu contohnya: react-key-index .sumber
toString()
untuk mengonversi ke string alih-alih meninggalkan sebagai nomor. Apakah ini penting untuk diingat?key
juga. Tidak yakin mengapa mereka mengubahnya.key
selalu berakhir menjadi sebuah String pula.Ini mungkin atau tidak membantu seseorang, tetapi itu mungkin referensi cepat. Ini juga mirip dengan semua jawaban yang disajikan di atas.
Saya memiliki banyak lokasi yang menghasilkan daftar menggunakan struktur di bawah ini:
Setelah sedikit trial and error (dan beberapa frustrasi), menambahkan properti kunci ke blok terluar menyelesaikannya. Perhatikan juga bahwa tag <> sekarang diganti dengan tag sekarang.
Tentu saja, saya secara naif menggunakan indeks iterasi (indeks) untuk mengisi nilai kunci dalam contoh di atas. Idealnya, Anda akan menggunakan sesuatu yang unik untuk item daftar.
sumber
Peringatan: Setiap anak dalam array atau iterator harus memiliki prop "kunci" yang unik.
Ini adalah peringatan karena untuk item array yang akan kita ulas membutuhkan kemiripan yang unik.
Bereaksi menangani iterasi komponen rendering sebagai array.
Cara yang lebih baik untuk menyelesaikan ini adalah memberikan indeks pada item-item array yang akan Anda ulangi misalnya.
indeks Bereaksi alat peraga bawaan.
sumber
Cukup tambahkan kunci unik ke Komponen Anda
sumber
Periksa: key = undef !!!
Anda juga mendapat pesan peringatan:
jika kode Anda selesai dengan benar, tetapi jika aktif
someValue tidak terdefinisi !!! Silakan periksa ini dulu. Anda dapat menghemat waktu.
sumber
Solusi terbaik untuk mendefinisikan kunci unik dalam bereaksi: di dalam peta Anda menginisialisasi nama pos kemudian kunci didefinisikan dengan kunci = {post.id} atau dalam kode saya Anda lihat saya mendefinisikan item nama kemudian saya mendefinisikan kunci dengan kunci = {item.id }:
sumber
Ini peringatan, Tetapi mengatasi ini akan membuat Reacts memberikan lebih cepat ,
Ini karena
React
perlu mengidentifikasi secara unik setiap item dalam daftar. Katakanlah jika keadaan elemen dari daftar itu berubah dalam BereaksiVirtual DOM
maka Bereaksi perlu mencari tahu elemen mana yang berubah dan di mana dalam DOM itu perlu berubah sehingga browser DOM akan disinkronkan dengan Reacts Virtual DOM.Sebagai solusi, cukup perkenalkan
key
atribut untuk setiapli
tag. Inikey
harus menjadi nilai unik untuk setiap elemen.sumber
key
prop. Jika Anda tidak menyediakan satu, Bereaksi akan menetapkan satu secara otomatis (indeks iterasi saat ini).key={i}
. Jadi itu tergantung pada data array Anda. Sebagai contoh, jika Anda memiliki daftar["Volvo", "Tesla"]
, maka jelas Volvo diidentifikasi oleh kunci0
dan Tesla dengan1
- karena itu adalah urutan mereka akan muncul dalam loop. Sekarang jika Anda menyusun ulang susunan kuncinya, tombol ditukar. Untuk Bereaksi, karena "objek"0
masih di atas, ia akan lebih menafsirkan perubahan ini sebagai "ganti nama", daripada menyusun ulang. Kunci yang benar di sini perlu, dalam urutan,1
kemudian0
. Anda tidak selalu memesan ulang pertengahan runtime, tetapi ketika Anda melakukannya, itu risiko.Ini akan menyelesaikan masalah.
sumber
Saya mengalami pesan kesalahan ini karena
<></>
dikembalikan untuk beberapa item dalam array ketika sebaliknyanull
perlu dikembalikan.sumber
Saya memperbaiki ini menggunakan Guid untuk setiap kunci seperti ini: Menghasilkan Guid:
Dan kemudian menetapkan nilai ini ke marker:
sumber
Pada dasarnya Anda tidak harus menggunakan indeks array sebagai kunci unik. Alih-alih, Anda dapat menggunakan a
setTimeout(() => Date.now(),0)
untuk mengatur kunci unik atau uniquid uuid atau cara lain yang akan menghasilkan id unik tetapi tidak indeks array sebagai id unik.sumber