React Top-Level API: cloneElement

本系列文章是本人学习相关知识时所积累的笔记,以记录自己的学习历程,也为了方便回顾知识;故文章内容较为随意简练,抱着学习目的来的同学务必转移他处,以免我误人子弟~

React: cloneElement

工作中遇到个需求,有个表单字段的值是由数组构成,而且数组的长度不确定。于是我想着使用 React 封装个表单组件,可以实现添加任何子表单组件并且输出数组值,如:

<DynamicFieldComponent>
	<Input />
</DynamicFieldComponent>

输出的值则可以是
["字符串1","字符串2","字符串3","字符串4",...]

如果子表单组件是 Select

<DynamicFieldComponent>
	<Select multiple={false}>
		<Select.option>选项1</Select.option>
		<Select.option>选项2</Select.option>
		<Select.option>选项3</Select.option>
	</Select>
</DynamicFieldComponent>

输出的值则可以是
["选项1","选项2","选项1","选项3",...]

问题

在调试阶段,我先在 DynamicFieldComponent 组件中写死了子表单组件,即不能接收任意的表单组件,并在写死的表单组件上绑定了事件处理函数:

// DynamicFieldComponent 
...
...
handleChange(){
	...
}
render(){
	let items = this.state.keys.map((key,index)=>{
		return <Input onChange={this.handleChange} key={key} />;
	})
	return(
		{items}
	)
}

现在 DynamicFieldComponent 中,我是用 this.props.children 来接收子表单组件的,这时我无法直接将事件处理函数绑定在 this.props.children 上面。

解决

其实在 React 中,提供了一些 API 供我们使用,这里我们需要使用的两个api是React.Children.onlyReact.cloneElement

  • React.Children.only用来处理this.props.children,只接受仅一个元素的this.props.children,返回React.ReactElement数据类型
  • React.cloneElement 第一个参数接收类型为 React.ReactElement 的元素,第二个参数接收该元素的期待的属性值

所以我先用 React.Children.onlyReact.ReactNode 转为 React.ReactElement ,再使用 React.cloneElement 克隆出一个新的元素,并同时指定事件处理函数,问题就得到解决了。

// DynamicFieldComponent 
...
...
handleChange(){
	...
}
render(){
    const child = React.Children.only(this.props.children);
    const items = this.state.keys.map((key: number, index: number) => {
      	  const childElement = React.cloneElement(child, {
      	      onChange: (value: any) => this.handleChange(key, value),
     	   });
      	  return childElement;
    }
    return(
    	{items}
    )
}

最后放上这个组件的完整代码:github:zyhcool

参考资料
官方文档:React.cloneElement
简书:[React] this.props.children和React.cloneElement

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值