“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
未经允许,禁止转载
在Web开发中,表单是用户交互的重要组成部分。
成熟的Web前端组件库 如 AntDesign、FussionDesign中,对于Form的如何使用,有一套约定俗成的规范。
比如 在Form.Item中,使用的组件,是非常不建议手动传入 value 和 onChange
<Form.Item>
<Input value={value} onChange={onChange} />
</Form.Item>
如上所示,是非常错误的一种用法,因为 Form.Item 会注入 value和onChange 到 Input 组件中。
在大多数场景下,开发者是不需要手动 传入 value和onChange的。
更好的实现方法是,将数据状态和修改数据 统统交给Form组件统一管理。
比如,我们会用 useForm 统一管理表单
const form = Form.useForm();
return (
<Form form={form}>
<Form.Item name='userName'>
<Input />
</Form.Item>
</Form>
)
如果想用 初始化值,可以通过 Form的initValues属性
<Form initialValues={{userName: 'xiaoming‘}} form={form}>
// 此处省略。。。
还可以统一处理 form表单的数据状态变化,这里用了onValueChange处理表单中所有数据的变化
const form = Form.useForm();
const onValueChange = async (changedValues: any) => {
if (changedValues.userName) {
// 此处实现 userName 变化后的回调
form.setFieldsValue({ autopost: false });
}
}
<Form
form={form}
onValuesChange={onValueChange}
>
<Form.Item name='userName'>
<Input />
</Form.Item>
</Form>
这种方法的好处是管理起来更加方便,更加直观
强控组件
强控组件是指 组件的 数据状态 和 修改方法 都交给外部去实现的 一种组件
如上面的input就是强控组件,它对外提供了value和onChange Api,外部使用起来更加容易
而众所周知,表单组件 只要稍微变化一点,我们就必须重新封装个 新的表单组件,比如下面
这个需求只是简单的 在input 右面加一个链接,有的网友可能会这样实现
<Form.Item name='userName'>
<Input />
<a href='....'>链接</a>
</Form.Item>
这样实现是完全错误的,因为Form.Item下,应该只有一个组件,这样才能正确地 注入 value 和 onChange
所以 这个需求应该这样实现,我们需要写一个自定义组件
function CustomComponent(props: { value?: string; onChange?: (v: string) => viod;} ) {
return (
<>
<Input {...props} />
<a href='https://juejin.cn'>链接</a>
</>
)
}
然后在表单中,使用这个自定义表单组件
<Form.Item>
<CustomComponent />
</Form.Item>
这样我们这个需求就完成了,我们也实现了个最简单的表单强控组件
弱控组件
弱控组件 就是指 数据状态和修改方法 不受外部控制的组件
比如下面就是一个 通过button单击 通过input的ref获取value的方法
相比强控组件来说,弱控组件的代码数量上会少一丢丢,但是 弱控组件 仅适合在表单结构简单的时候
如果像上面这种表单结构比较复杂的时候,还是强烈推荐 使用 强控组件 管理表单