React.Children.map()
tidak ada contoh yang bagus , saya tidak mengerti cara mengetiknya:
/*
<CheckboxGroup ...>
<Checkbox ... />
<Checkbox ... />
<Checkbox ... />
</CheckboxGroup>
*/
// Child
class Checkbox extends React.Component<CheckboxProps, void> {
// ...
}
// Parent
class CheckboxGroup extends React.Component<CheckboxGroupProps, void> {
// ...
render() {
const checkboxes = React.Children.map(this.props.children, checkbox =>
React.cloneElement(checkbox, {
name: this.props.name,
checked: this.props.checkedValues.includes(checkbox.props.value),
onChange: this.handleCheckboxChange.bind(this)
})
);
return (
<div>
{checkboxes}
</div>
);
}
}
(contoh yang sangat umum, lihat http://stackoverflow.com/a/32371612/990356 )
this.props.children
?React.cloneElement()
?React.Children.map()
?Sebagian besar waktu saya berakhir dengan kesalahan berikut: Type 'string' is not assignable to type 'ReactElement<any>'
, lihat #8131
silakan kirim permintaan tarik. Saya akan mengulasnya.
@vvakame Saya tidak bisa, saya tidak mengerti cara kerjanya
saya juga. silakan membuat percakapan dengan penulis definisi.
Ping @vsiao @thasner @basarat @pspeter3 @beckend
Daftar ping/penulis berdasarkan:
Anda harus mengetik-beranotasi atau mengetik-menegaskan checkbox
secara eksplisit karena tidak ada jaminan bahwa this.props.children
tidak berisi nilai non-ReactElement. Misalnya:
React.Children.map(this.props.children, (checkbox: React.ReactElement<CheckboxProps>) =>
React.cloneElement(checkbox) // should be ok
);
@vsiao terima kasih banyak, berhasil!
Pertanyaan:
const checkboxes = React.Children.map(this.props.children, checkbox =>
React.cloneElement(checkbox, {
name: this.props.name,
checked: this.props.checkedValues.includes(checkbox.props.value),
onChange: this.handleCheckboxChange.bind(this)
})
);
Larutan:
const checkboxes = React.Children.map(props.children, (checkbox: React.ReactElement<CheckboxPropsInternal>) =>
React.cloneElement(checkbox, {
checked: props.checkedValues.includes(checkbox.props.value),
onChange: handleCheckboxChange
})
);
@tkrotoff Anda juga bisa melakukan ini:
React.Children.map(this.props.children, (child: number) => {
return child + 1
})
Ini dan solusi yang disarankan hanya memanfaatkan fakta bahwa React.Children.map
tidak diketik dengan kuat. Anda mungkin juga telah menggunakan any
alih-alih tipe Checkbox
karena tidak ada jaminan bahwa itu akan menjadi tipe anak-anak. Ini berarti Anda mungkin mengalami kesalahan runtime jika ada yang salah menggunakan komponen dengan meneruskan string.
Bagaimana dengan ini:
class Slot extends React.PureComponent {
render () {
return this.props.children
}
}
const isReactElement = (obj: {}): obj is React.ReactElement<{}> => {
return obj.hasOwnProperty('type')
}
const isSlot = (obj: {}): obj is Slot => {
return isReactElement(obj) && obj.type === Slot
}
const getSlots = (children: React.ReactNode) => React.Children.map(children, (child: React.ReactChild): JSX.Element | null => {
if (isReactElement(child) && isSlot(child)) {
return child
}
return null
})
class ComponentWithSlots extends React.PureComponent {
render () {
const [header, footer] = getSlots(this.props.children)
return (
<div>
{header}
<div>
<h1>Welcome</h1>
<p>This is my lovely component with slots</p>
</div>
{footer}
</div>
)
}
}
class MyComponent extends React.PureComponent {
render () {
return (
<ComponentWithSlots>
<Slot>My Header!</Slot>
<Slot>
<div>github: @variousauthors</div>
</Slot>
</ComponentWithSlots>
)
}
}
Yang akan membuat:
My Header!
Welcome
This is my lovely component with slots
github: <strong i="17">@variousauthors</strong>
Pendekatan ini mengambil keuntungan dari jenis informasi yang kami _do_ miliki, yaitu bahwa ReactChild
mungkin menjadi ReactElement
(Saya telah menggunakan type
untuk mendeteksi ini, tetapi Anda bisa saja lebih berhati-hati jika Anda mau). Kita juga bisa lebih deskriptif dan mengelaborasi bahwa Slot
. Saya melihat perpustakaan UI menerapkan pola di mana kelas memiliki slotnya sendiri. Sesuatu seperti:
<Dropdown>
<Dropdown.Header>
<FancyIcon>My Header!</FancyIcon>
</Dropdown.Header>
{dropdownItems}
</Dropdown>
Dengan cara ini pengguna jelas tentang arti dari setiap slot. Anak-anak lainnya (yang tidak diurai sebagai slot) dibiarkan dalam koleksi yang disebut children
dan dirender a la cart, memungkinkan pengguna untuk tetap menggunakan children
normal sambil memesan perilaku khusus untuk slot kustom.
EDIT: React tampaknya memiliki metode React.isValidElement
yang dapat Anda gunakan sebagai pengganti isReactElement
kustom saya.
EDIT: Hal lain yang dapat Anda lakukan adalah mengetikkan properti children
pada komponen Anda, sehingga pengguna hanya diizinkan untuk memasukkan Kotak Centang sebagai anak-anak. Ini akan membantu menghindari kesalahan runtime tersebut.
Komentar yang paling membantu
Pertanyaan:
Larutan: