Web前端编程技巧:强控组件 和 弱控组件

1,070 阅读2分钟

“我报名参加金石计划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,外部使用起来更加容易

而众所周知,表单组件 只要稍微变化一点,我们就必须重新封装个 新的表单组件,比如下面

image.png

这个需求只是简单的 在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的方法

相比强控组件来说,弱控组件的代码数量上会少一丢丢,但是 弱控组件 仅适合在表单结构简单的时候

image.png

如果像上面这种表单结构比较复杂的时候,还是强烈推荐 使用 强控组件 管理表单