为什么 Form 组件中的表单控件不用 value 和 onChange 也能受控?

大家好,我是麦当。

我们写 React 的时候,一般想要让 input 元素受控,都需要为其添加 valueonChange 这两个属性,如下:

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 那一部分。

相关推荐
脑袋大大的32 分钟前
判断当前是否为钉钉环境
开发语言·前端·javascript·钉钉·企业应用开发
军军君0141 分钟前
基于Springboot+UniApp+Ai实现模拟面试小工具二:后端项目搭建
前端·javascript·spring boot·spring·微信小程序·前端框架·集成学习
quweiie1 小时前
tp8.0\jwt接口安全验证
前端·安全·jwt·thinkphp
xiaoyan20152 小时前
最新Flutter3.32+Dart3仿微信App聊天实例
前端·flutter·dart
汪敏wangmin2 小时前
Fiddler-抓包后直接生成Loadrunner脚本或者Jmeter脚本
前端·jmeter·fiddler
彤银浦3 小时前
Web学习笔记3
前端·笔记·学习·html5
江城开朗的豌豆3 小时前
退出登录后头像还在?这个缓存问题坑过多少前端!
前端·javascript·vue.js
江城开朗的豌豆3 小时前
Vue的'读心术':它怎么知道数据偷偷变了?
前端·javascript·vue.js
江城开朗的豌豆3 小时前
手把手教你造一个自己的v-model:原来双向绑定这么简单!
前端·javascript·vue.js
我在北京coding3 小时前
el-tree 懒加载 loadNode
前端·vue.js·elementui