Saya mencoba menemukan cara yang tepat untuk mendefinisikan beberapa komponen yang dapat digunakan secara umum:
<Parent>
<Child value="1">
<Child value="2">
</Parent>
Ada logika yang terjadi untuk rendering antara komponen orang tua dan anak-anak, Anda bisa bayangkan <select>
dan<option>
sebagai contoh dari logika ini.
Ini adalah implementasi tiruan untuk tujuan pertanyaan:
var Parent = React.createClass({
doSomething: function(value) {
},
render: function() {
return (<div>{this.props.children}</div>);
}
});
var Child = React.createClass({
onClick: function() {
this.props.doSomething(this.props.value); // doSomething is undefined
},
render: function() {
return (<div onClick={this.onClick}></div>);
}
});
Pertanyaannya adalah kapan pun Anda menggunakan {this.props.children}
untuk mendefinisikan komponen pembungkus, bagaimana Anda mewariskan beberapa properti untuk semua anak-anaknya?
javascript
reactjs
react-jsx
plus-
sumber
sumber
Jawaban:
Mengkloning anak-anak dengan alat peraga baru
Anda dapat menggunakan React.Children untuk beralih ke anak-anak, dan kemudian mengkloning setiap elemen dengan alat peraga baru (dangkal digabung) menggunakan React.cloneElement misalnya:
Fiddle: https://jsfiddle.net/2q294y43/2/
Memanggil anak-anak sebagai fungsi
Anda juga dapat memberikan alat peraga kepada anak-anak dengan alat bantu render . Dalam pendekatan ini anak-anak (yang dapat
children
atau nama prop lainnya) adalah fungsi yang dapat menerima argumen apa pun yang ingin Anda sampaikan dan mengembalikan anak-anak:Alih-alih
<React.Fragment>
atau hanya<>
Anda juga dapat mengembalikan array jika Anda inginkan.Fiddle: https://jsfiddle.net/ferahl/y5pcua68/7/
sumber
value
diteruskan kedoSomething
hilang.Untuk cara yang sedikit lebih bersih untuk melakukannya, cobalah:
Sunting: Untuk digunakan dengan banyak anak individual (anak itu sendiri harus menjadi komponen) yang dapat Anda lakukan. Diuji dalam 16.8.6
sumber
this.props.children
) kecloneElement
... yang mengharapkan ... elemen.React.Children.only
fungsi mengembalikan satu-satunya anak atau melempar pengecualian jika ada beberapa (ini tidak akan ada jika tidak ada use case).Coba ini
Itu bekerja untuk saya menggunakan react-15.1.
sumber
React.cloneElement()
secara langsung tanpa mengelilinginya dalam<div>
tag? Karena bagaimana jika anak itu adalah<span>
(atau sesuatu yang lain) dan kami ingin mempertahankan tipe elemen tag-nya?React.cloneElement(React.Children.only(this.props.children), {...this.props})
yang akan menimbulkan kesalahan jika diteruskan lebih dari satu anak. Maka Anda tidak perlu membungkusnya dengan div.let {children, ...acyclicalProps} = this.props
kemudianReact.cloneElement(React.Children.only(children), acyclicalProps)
.Lewati alat peraga untuk mengarahkan anak-anak.
Lihat semua jawaban lain
Lulus berbagi, data global melalui pohon komponen melalui konteks
Penafian: Ini adalah jawaban yang diperbarui, yang sebelumnya menggunakan API konteks lama
Ini didasarkan pada prinsip Konsumen / Menyediakan. Pertama, buat konteks Anda
Kemudian gunakan via
dan
Contoh lengkap, kode semi-pseudo.
1 https://facebook.github.io/react/docs/context.html
sumber
this.context
) - itu tidak secara ajaib menggabungkan konteks dengan alat peraga. Anda harus sengaja mengatur dan menggunakan konteksnya, yang merupakan hal lain.Melewati Alat Peraga untuk Anak-Anak yang Bersarang
Dengan pembaruan ke Bereaksi 16.6 Anda sekarang dapat menggunakan React.createContext dan contextType .
sumber
this
konteksAnda dapat menggunakan
React.cloneElement
, lebih baik untuk mengetahui cara kerjanya sebelum Anda mulai menggunakannya di aplikasi Anda. Itu diperkenalkan diReact v0.13
, baca terus untuk informasi lebih lanjut, jadi sesuatu bersama ini bekerja untuk Anda:Jadi bawalah baris-baris dari React dokumentasi agar Anda memahami bagaimana semuanya bekerja dan bagaimana Anda dapat menggunakannya:
lebih lanjut di sini ...
sumber
Cara terbaik, yang memungkinkan Anda melakukan transfer properti
children
seperti fungsiContoh:
sumber
nested components
. Bereaksi tidak memiliki pola bersarang, hanya komposisi. Ya, anak-anak harus menjadi fungsi, tidak ada konflik, karena ini anak JSX yang valid. Bisakah Anda memberi contohnesting components
?<Parent>{props => <Nest><ChildComponent /></Nest>}</Parent>
alih-alih (tidak bekerja)<Parent><Nest>{props => <ChildComponent />}</Nest></Parent>
jadi saya setuju ini adalah jawaban terbaikTypeError: children is not a function
Saya perlu memperbaiki jawaban yang diterima di atas untuk membuatnya berfungsi dengan menggunakan itu daripada pointer ini . Ini dalam lingkup fungsi peta tidak memiliki fungsi doSomething yang ditentukan.
Pembaruan: perbaikan ini untuk ECMAScript 5, di ES6 tidak perlu dalam var yang = ini
sumber
bind()
doSomething
mengambil objek, sepertidoSomething: function(obj) { console.log(obj) }
dan di dalam Child Anda akan dipanggilthis.props.doSomething(obj)
untuk logout"obj"
apply
metode. menggunakanbind()
dalam fungsi render akan membuat fungsi baru setiap kali metode render dipanggil.Cara bersih mempertimbangkan satu atau lebih anak
sumber
this.props
. Secara umum saya hanya merekomendasikan kloning dengan alat peraga tertentu, bukan seluruh shebang.{...this.props}
tidak bekerja untuk saya, apakah jalannya{...child.props}
benar?React.Children.map(children, child => React.cloneElement(child, props))
Tidak ada jawaban yang membahas masalah memiliki anak yang TIDAK Bereaksi komponen, seperti string teks. Penanganannya bisa seperti ini:
sumber
Anda tidak lagi membutuhkan
{this.props.children}
. Sekarang Anda dapat membungkus komponen anak Anda menggunakanrender
diRoute
dan lulus alat peraga seperti biasa:sumber
Parent.jsx:
Child.jsx:
dan main.jsx:
lihat contoh di sini: https://plnkr.co/edit/jJHQECrKRrtKlKYRpIWl?p=preview
sumber
Mungkin Anda juga dapat menemukan fitur yang bermanfaat ini, meskipun banyak orang menganggap ini sebagai anti-pola yang masih dapat digunakan jika Anda tahu apa yang Anda lakukan dan merancang solusi Anda dengan baik.
Berfungsi sebagai Komponen Anak
sumber
Jika Anda memiliki banyak anak yang ingin Anda sampaikan alat peraga , Anda dapat melakukannya dengan cara ini, menggunakan React.Children.map:
Jika komponen Anda hanya memiliki satu anak, tidak perlu pemetaan, Anda bisa langsung cloneElement:
sumber
Menurut dokumentasi
cloneElement()
Jadi cloneElement adalah apa yang akan Anda gunakan untuk menyediakan alat peraga khusus untuk anak-anak. Namun ada beberapa anak dalam komponen dan Anda harus mengulanginya. Apa jawaban lain yang disarankan agar Anda memetakannya menggunakan
React.Children.map
. NamunReact.Children.map
tidak sepertiReact.cloneElement
perubahan kunci dari elemen ditambahkan dan tambahan.$
sebagai awalan. Periksa pertanyaan ini untuk detail lebih lanjut: React.cloneElement di dalam React.Children.map menyebabkan kunci elemen berubahJika Anda ingin menghindarinya, Anda harus memilih
forEach
fungsi sepertisumber
Lebih jauh ke jawaban @and_rest, ini adalah bagaimana saya mengkloning anak-anak dan menambahkan kelas.
sumber
Saya pikir render prop adalah cara yang tepat untuk menangani skenario ini
Anda membiarkan Orang Tua menyediakan alat peraga yang diperlukan yang digunakan dalam komponen anak, dengan refactoring kode Orang Tua untuk melihat sesuatu seperti ini:
Kemudian di Komponen anak Anda dapat mengakses fungsi yang disediakan oleh orang tua dengan cara ini:
Sekarang struktur fianl akan terlihat seperti ini:
sumber
Metode 1 - mengkloning anak-anak
Metode 2 - gunakan konteks yang dapat disusun
Konteks memungkinkan Anda untuk meneruskan penyangga ke komponen anak dalam tanpa secara eksplisit meneruskannya sebagai penyangga melalui komponen di antaranya.
Konteks dilengkapi dengan kelemahan:
Menggunakan konteks yang dapat dikomposisikan
sumber
{children}:{children:ReactNode}
?"children"
bertipeReactNode
Cara paling licin untuk melakukan ini:
sumber
Untuk siapa pun yang memiliki elemen anak tunggal ini harus melakukannya.
sumber
Apakah ini yang Anda butuhkan?
sumber
Beberapa alasan React.children tidak bekerja untuk saya Inilah yang bekerja untuk saya.
Saya hanya ingin menambahkan kelas untuk anak itu. mirip dengan mengubah prop
Kuncinya di sini adalah React.cloneElement . Anda dapat melewati prop apa pun dengan cara yang sama
sumber
Render props adalah pendekatan paling akurat untuk masalah ini. Alih-alih meneruskan komponen anak ke komponen induk sebagai alat bantu anak-anak, biarkan orang tua merender komponen anak secara manual. Render adalah alat peraga bawaan yang bereaksi, yang mengambil parameter fungsi. Dalam fungsi ini Anda dapat membiarkan komponen induk merender apa pun yang Anda inginkan dengan parameter khusus. Pada dasarnya ia melakukan hal yang sama seperti alat peraga anak tetapi lebih dapat disesuaikan.
Contoh di codepen
sumber
Saat menggunakan komponen fungsional, Anda akan sering mendapatkan
TypeError: Cannot add property myNewProp, object is not extensible
kesalahan saat mencoba mengaktifkan properti baruprops.children
. Ada pekerjaan sekitar untuk ini dengan mengkloning alat peraga dan kemudian mengkloning anak itu sendiri dengan alat peraga baru.sumber