使用场景:父子组件嵌套时的隐式交互,父组件要往子组件的【props】中入特定的属性.如受控组件.
例1:【Form】与【FormItem】.
【Form】向【FormItem的props】注入【onChange,value】等.
<Form>
<FormItem>
<Input/>
</FormItem>
<FormItem>
<Input/>
</FormItem>
<FormItem>
<Input/>
</FormItem>
</Form>
例2:【Select】与【Option】.
【Select】向【Option的props】注入【onClick,onChange,isSelected】等.
<Select>
<Option />
<Option />
<Option />
</Select>
山寨版写法实现:向子组件注入props;这种写法的问题在于:1.props的类型非正统推断得出,而是使用了as any,2.没有遵循不可变值的约定.
props.children.map((children) => {
const childrenProps = (children as any).props;
childrenProps.onClick = (code: string) => handleClickItem(code);
childrenProps.isSelected = selected.includes(childrenProps.code);
return children;
});
官方正统版写法:
第一步:父组件的children类型需要声明成FunctionComponentElement<SunProps>;
FunctionComponentElement是核心,从react中引入;
type FatherProps = {
...其它属性,
children: FunctionComponentElement<SunProps>[];
};
第二步:通过两个API在父组件中,对子组件进行加工.
1.React.Children.map(参数1,参数2):参数1:就是props.children,参数2:回调函数:(child)=>newChild,其中child就是子组件的每一项,newChild就是用新的替换掉旧的.说到底,这个函数与props.children.map(item=>newItem)几乎一个效果,只是完善了一些内置兼容性检查等细节,多数时候,你使用后者同样能达到效果.
2.React.cloneElement(参数1,参数2):参数1:props.children数组中的一项,参数2:要注入(合并进)该项的props.返回值是生成一个新的child元素.
<View className={localClassName} style={props.style}>
{React.Children.map(props.children, (child) =>
React.cloneElement(child, {
onClick: (code: string) => handleClickItem(code),
isSelected: selected.includes(child.props.code),
})
)}
</View>
完