大家好,我是麦当。
我们写 React 的时候,一般想要让 input
元素受控,都需要为其添加 value
和 onChange
这两个属性,如下:
html
<input value={val} onChange={(e) => setVal(e.target.value)} />
但是用过 Antd 4、5 的人一定知道,Form 表单中的 FormItem,只要添加了 name 属性,便可以自动控制表单控件。本文就来聊聊 Form 组件是如何实现使表单元素自动受控的。
jsx
<Form
initialValues={{ book: '玩转 React Hooks' }}
onFinish={(data: any) => {
console.log(data)
}}
>
<Form.Item label="title" name="title">
<Input placeholder="please enter title"/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
原理
FormItem 里用到了 React.cloneElement 这个 api, FormItem 在渲染 children 前,会对 children 进行一次克隆,然后新增了 value 和 onChange 这两个 props 作为 children 的参数,这样就实现了表单控件的受控。然后在其他地方对数据进行统一管理。
代码
源码部分可以在这里查看,核心是 cloneElement 那一部分。