- Misalkan saya memiliki kelas B React, yang membuat dua kelas anak, C1 dan C2.
- C1 berisi bidang input. Saya akan merujuk ke bidang input ini sebagai Foo.
- Tujuan saya adalah membiarkan C2 bereaksi terhadap perubahan di Foo.
Saya telah menemukan dua solusi, tetapi tidak satu pun dari keduanya terasa benar.
Solusi pertama:
- Tetapkan P status
state.input
,. - Buat
onChange
fungsi dalam P, yang mengambil acara dan setstate.input
. - Berikan ini
onChange
ke C1 sebagaiprops
, dan biarkan C1 mengikatthis.props.onChange
keonChange
Foo.
Ini bekerja. Setiap kali nilai Foo berubah, ia memicu a setState
di P, jadi P akan memiliki input untuk diteruskan ke C2.
Tapi rasanya tidak tepat karena alasan yang sama: Saya mengatur keadaan elemen induk dari elemen anak. Ini tampaknya mengkhianati prinsip desain React: aliran data satu arah.
Apakah ini yang seharusnya saya lakukan, atau adakah solusi yang lebih alami?
Solusi kedua:
Masukkan saja Foo ke P.
Tetapi apakah ini prinsip desain yang harus saya ikuti ketika saya menyusun aplikasi saya — menempatkan semua elemen bentuk di render
kelas tingkat tertinggi?
Seperti dalam contoh saya, jika saya memiliki rendering besar C1, saya benar-benar tidak ingin menempatkan seluruh render
C1 ke render
P hanya karena C1 memiliki elemen bentuk.
Bagaimana saya harus melakukannya?
Jawaban:
Jadi, jika saya memahami Anda dengan benar, solusi pertama Anda adalah menyarankan Anda menjaga status pada komponen root Anda? Saya tidak dapat berbicara untuk pencipta React, tetapi secara umum, saya menemukan ini sebagai solusi yang tepat.
Mempertahankan keadaan adalah salah satu alasan (setidaknya saya pikir) bahwa Bereaksi diciptakan. Jika Anda pernah menerapkan sisi klien pola negara Anda sendiri untuk berurusan dengan UI dinamis yang memiliki banyak bagian bergerak yang saling bergantung, maka Anda akan menyukai Bereaksi, karena hal ini mengurangi banyak rasa sakit manajemen negara bagian ini.
Dengan menjaga status lebih lanjut dalam hierarki, dan memperbaruinya melalui acara, aliran data Anda masih cukup banyak searah, Anda hanya merespons peristiwa di komponen Root, Anda tidak benar-benar mendapatkan data di sana melalui ikatan dua arah, Anda memberi tahu komponen Root bahwa "hei, sesuatu terjadi di sini, periksa nilainya" atau Anda melewatkan status beberapa data dalam komponen anak untuk memperbarui status. Anda mengubah status di C1, dan Anda ingin C2 menyadarinya, jadi, dengan memperbarui status di komponen Root dan rendering ulang, properti C2 sekarang disinkronkan karena keadaan diperbarui di komponen Root dan diteruskan .
sumber
C2
memilikigetInitialState
data dan dirender
dalamnya digunakanthis.state.data
?Setelah menggunakan React untuk membangun aplikasi sekarang, saya ingin berbagi pemikiran tentang pertanyaan ini yang saya tanyakan setengah tahun yang lalu.
Saya sarankan Anda untuk membaca
Posting pertama sangat membantu untuk memahami bagaimana Anda harus menyusun aplikasi Bereaksi Anda.
Flux menjawab pertanyaan mengapa Anda harus menyusun aplikasi Bereaksi Anda dengan cara ini (berbeda dengan cara menyusunnya). Bereaksi hanya 50% dari sistem, dan dengan Flux Anda bisa melihat seluruh gambar dan melihat bagaimana mereka membentuk sistem yang koheren.
Kembali ke pertanyaan.
Adapun solusi pertama saya, benar-benar OK untuk membiarkan pawang berbalik arah, karena data masih berjalan satu arah.
Namun, apakah membiarkan pawang memicu setState di P dapat benar atau salah tergantung pada situasi Anda.
Jika aplikasi ini adalah konverter Markdown sederhana, C1 menjadi input mentah dan C2 menjadi output HTML, tidak apa-apa membiarkan C1 memicu setState di P, tetapi beberapa orang mungkin berpendapat ini bukan cara yang disarankan untuk melakukannya.
Namun, jika aplikasi adalah daftar todo, C1 menjadi input untuk membuat todo baru, C2 daftar todo dalam HTML, Anda mungkin ingin menangani untuk naik dua tingkat daripada P - ke
dispatcher
, yang memungkinkanstore
pembaruandata store
, yang kemudian mengirim data ke P dan mengisi tampilan. Lihat artikel Flux itu. Berikut ini sebuah contoh: Flux - TodoMVCSecara umum, saya lebih suka cara yang dijelaskan dalam contoh daftar todo. Semakin sedikit status yang Anda miliki di aplikasi Anda, semakin baik.
sumber
Lima tahun kemudian dengan diperkenalkannya React Hooks sekarang ada cara yang jauh lebih elegan untuk melakukannya dengan menggunakan useContext hook.
Anda mendefinisikan konteks dalam lingkup global, mengekspor variabel, objek dan fungsi dalam komponen induk dan kemudian membungkus anak-anak di App dalam konteks yang disediakan dan mengimpor apa pun yang Anda butuhkan dalam komponen anak. Di bawah ini adalah bukti konsep.
Anda dapat menjalankan contoh ini di editor Code Sandbox.
sumber
Solusi pertama, dengan menjaga status dalam komponen induk , adalah yang benar . Namun, untuk masalah yang lebih kompleks, Anda harus berpikir tentang beberapa perpustakaan manajemen negara , redux adalah yang paling populer digunakan dengan reaksi.
sumber
Saya terkejut bahwa tidak ada jawaban dengan solusi Bereaksi idiomatis langsung pada saat saya sedang menulis. Jadi ini dia (bandingkan ukuran dan kompleksitasnya dengan yang lain):
Setiap cara terkendali
input
(cara kerja idiomatis dengan formulir di Bereaksi) memperbarui status induk dalamonChange
panggilan baliknya dan masih tidak mengkhianati apa pun.Perhatikan baik-baik komponen C1, misalnya. Apakah Anda melihat perbedaan yang signifikan dalam cara bagaimana
C1
dan built-ininput
menangani komponen perubahan negara? Anda tidak boleh, karena tidak ada. Mengangkat status dan meneruskan nilai / onChange pair adalah idiomatik untuk Bereaksi mentah. Tidak menggunakan referensi, seperti yang disarankan beberapa jawaban.sumber
this.state
, kembalinya hilang dalam render, dan beberapa komponen harus dibungkus dengan div atau sesuatu. Tidak tahu bagaimana saya melewatkan itu ketika saya menulis jawaban yang asli. Pasti karena kesalahan pengeditan.Jawaban yang lebih baru dengan contoh, yang menggunakan
React.useState
Menjaga status dalam komponen induk adalah cara yang disarankan. Orang tua perlu memiliki akses ke sana karena mengaturnya di dua komponen anak-anak. Memindahkannya ke kondisi global, seperti yang dikelola oleh Redux, tidak direkomendasikan untuk alasan yang sama mengapa variabel global lebih buruk daripada lokal pada umumnya dalam rekayasa perangkat lunak.
Ketika status berada dalam komponen induk, anak dapat memutasinya jika orangtua memberikan anak
value
danonChange
pawang dalam alat peraga (kadang-kadang disebut tautan nilai atau pola tautan negara ). Inilah cara Anda melakukannya dengan kait:Seluruh komponen induk akan merender ulang pada input input pada anak, yang mungkin tidak menjadi masalah jika komponen induk kecil / cepat untuk dirender ulang. Kinerja ulang membuat komponen induk masih bisa menjadi masalah dalam kasus umum (misalnya bentuk besar). Ini masalah yang diselesaikan dalam kasus Anda (lihat di bawah).
Pola tautan negara dan tidak ada render ulang orang tua lebih mudah diterapkan menggunakan perpustakaan pihak ke-3, seperti Hookstate - supercharged
React.useState
untuk mencakup berbagai kasus penggunaan, termasuk yang Anda miliki . (Penafian: Saya seorang penulis proyek).Begini tampilannya dengan Hookstate.
Child1
akan mengubah input,Child2
akan bereaksi padanya.Parent
akan memegang negara tetapi tidak akan membuat kembali saat perubahan negara, hanyaChild1
danChild2
akan.PS: ada banyak contoh di sini yang mencakup skenario yang serupa dan lebih rumit, termasuk data yang bersarang dalam, validasi negara, keadaan global dengan
setState
kait, dll. Ada juga contoh aplikasi online lengkap , yang menggunakan Hookstate dan teknik yang dijelaskan di atas.sumber
Anda harus mempelajari pustaka Redux dan ReactRedux. Ini akan menyusun status dan properti Anda di satu toko dan Anda dapat mengaksesnya nanti di komponen Anda.
sumber
Dengan React> = 16.3 Anda dapat menggunakan ref dan forwardRef, untuk mendapatkan akses ke DOM anak dari induknya. Jangan menggunakan referensi cara lama lagi.
Berikut ini contoh penggunaan kasing Anda:
Lihat Ref dan ForwardRef untuk info detail tentang ref dan forwardRef.
sumber
shouldComponentUpdate(nextProps, nextState)
Kode di bawah ini menggunakan
@bound
anotasi dari ES. Berikutnyababel-plugin-transform-decorators-legacy
dari BabelJS 6 dan properti-kelas (anotasi menetapkan nilai ini pada fungsi anggota yang mirip dengan bind):sumber
Konsep menyampaikan data dari orang tua ke anak dan sebaliknya dijelaskan.
sumber