ينقص React.Children.map()
مثالًا جيدًا ، ولا أفهم كيفية كتابته:
/*
<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>
);
}
}
(مثال شائع جدًا ، راجع http://stackoverflow.com/a/32371612/990356)
this.props.children
؟React.cloneElement()
؟React.Children.map()
؟في معظم الأوقات ينتهي بي الأمر بالخطأ التالي: Type 'string' is not assignable to type 'ReactElement<any>'
، راجع # 8131
الرجاء إرسال طلب سحب. سوف أراجعها.
vvakame لا أستطيع ، لا أفهم كيف من المفترض أن يعمل
أنا أيضا. يرجى إجراء محادثات مع مؤلفي التعريف.
بينغvsiaothasnerbasarat @ pspeter3beckend
قائمة Ping / المؤلفين على أساس:
ستحتاج إلى كتابة التعليق التوضيحي أو تأكيد الكتابة checkbox
صراحة لأنه لا يوجد ضمان بأن this.props.children
لا يحتوي على قيم غير ReactElement. على سبيل المثال:
React.Children.map(this.props.children, (checkbox: React.ReactElement<CheckboxProps>) =>
React.cloneElement(checkbox) // should be ok
);
vsiao thx كثيرا ، إنه يعمل!
سؤال:
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)
})
);
حل:
const checkboxes = React.Children.map(props.children, (checkbox: React.ReactElement<CheckboxPropsInternal>) =>
React.cloneElement(checkbox, {
checked: props.checkedValues.includes(checkbox.props.value),
onChange: handleCheckboxChange
})
);
tkrotoff ، يمكنك أيضًا القيام بذلك:
React.Children.map(this.props.children, (child: number) => {
return child + 1
})
هذا والحل المقترح يستفيدان فقط من حقيقة أن React.Children.map
غير مكتوب بقوة. ربما تكون قد استخدمت أيضًا any
بدلاً من النوع Checkbox
نظرًا لعدم وجود ضمان بأن هذا سيكون نوع الأطفال. هذا يعني أنه من المحتمل أن يكون لديك أخطاء في وقت التشغيل إذا أخطأ أي شخص في استخدام المكون عن طريق تمرير سلسلة.
وماذا عن هذا:
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>
)
}
}
الذي سيعرض:
My Header!
Welcome
This is my lovely component with slots
github: <strong i="17">@variousauthors</strong>
تستفيد هذه الطريقة من نوع المعلومات التي لدينا _do_ ، وهي أن ReactChild
قد يكون ReactElement
(لقد استخدمت type
لاكتشاف ذلك ، لكن يمكنك أن تكون كذلك أكثر حرصًا إذا أردت). يمكننا أيضًا أن نكون أكثر وصفًا وتفصيلًا أن Slot
. رأيت مكتبة UI تنفذ نمطًا حيث تم إرفاق فتحات خاصة بالفصول الدراسية. شيء مثل:
<Dropdown>
<Dropdown.Header>
<FancyIcon>My Header!</FancyIcon>
</Dropdown.Header>
{dropdownItems}
</Dropdown>
بهذه الطريقة يكون المستخدم واضحًا في معنى كل فتحة. يتم ترك بقية الأطفال (أولئك الذين لم يتم تحليلهم كفتحات) في مجموعة تسمى children
ويتم عرضهم في عربة التسوق ، مما يسمح للمستخدم بالاستمرار في استخدام children
طبيعي مع الاحتفاظ بسلوك خاص لـ فتحات مخصصة.
تحرير: يبدو أن React لديها طريقة React.isValidElement
يمكنك استخدامها بدلاً من isReactElement
.
تحرير: شيء آخر يمكنك القيام به هو كتابة الخاصية children
على المكون الخاص بك ، بحيث لا يُسمح للمستخدم إلا بالمرور في مربعات الاختيار كأطفال. سيساعد هذا في تجنب أخطاء وقت التشغيل هذه.
التعليق الأكثر فائدة
سؤال:
حل: