「这是我参与2022首次更文挑战的第36天,活动详情查看:2022首次更文挑战」。
写在前面
- 前面一篇文章已经简单说了一下,rc-form 到 rc-field-form 的改变,并且展示了 rc-field-form 的使用
- 今天这篇文章我们来一步一步实现完善我们自己的 rc-field-form
实现 Input 组件
- 下面我们简单封装一个 Input 组件,用作我们业务开发中的数据输入组件
export function Input(props) {
const { value = "", ...otherProps } = props;
return <input style={{ outline: "none" }} value={value} {...otherProps} />;
}
- 为啥不直接使用 input 框呢
- 其实跟我们的使用方法有关系
<Field name="user" label="账号" rules={userRules}>
<Input placeholder="请输入账号" />
</Field>
- 因为这里如果直接使用 input,就需要给它设置一个 value,但是我们前面也说了,所有的数据输入组件的 value 都要被统一管理起来
- 而这个数据托管的操作是在 Field 组件中做的,在使用 Input 组件时,是拿不到 value 的
- 所以在这里做了一层封装,从 props 中取出 value 值,默认为空字符串
""
,避免不传 value,导致数据输入时,出现非受控组件的报错
- 最后数据输入时,在 Field 组件内部,会将托管的 value 值传给 Input 组件,而 Input 组件的 props 中的 value 值也会变成真实输入的数据
创建数据仓库
- 我们需要创建一个 store 用来统一托管存储,用户输入的数据,然后让所有组件直接从 store 中获取数据,这样某个数据输入组件的数据发生改变,也只用更新自己即可,不会引起其他同级的数据输入组件进行更新,从而最大程度避免性能浪费
- 下面创建一个 FormStore,专门用于管理 Form 组件的所有数据
class FormStore {
constructor() {
this.store = {}; // 用于存放组件数据
}
// 实现操作状态的方法 get set
// 多个字段的 set 操作
setFieldsValue = (newStore) => {
this.store = {
...this.store,
...newStore,
};
};
// 多个字段的 get 操作
getFieldsValue = () => ({ ...this.store });
// 单个字段的 set 操作
setFieldValue = (field, val) => {
this.setFieldsValue({ [field]: val });
};
// 单个字段的 get 操作
getFieldValue = (fieldName) => this.store[fieldName];
// 暴露操作状态的方法
getForm = () => ({
getFieldsValue: this.getFieldsValue,
setFieldsValue: this.setFieldsValue,
setFieldValue: this.setFieldValue,
getFieldValue: this.getFieldValue,
});
}
- 在上面的 FormStore 中,使用 store 用来存放数据
- 实现了四个方法,其中 setFieldsValue 与 getFieldsValue 是用于多字段的数据存与取,setFieldValue 与 getFieldValue 是用于单字段的数据存与取
- 最后实现了一个 getForm 方法,用于暴露数据仓库 store 的相关操作方法
小结
- 这篇文章,我们在组件之外,创建了一个数据仓库,用于集中管理 Form 组件的所有数据
- 这个数据仓库独立与 Form,那它们之间如何进行交互呢?如何在更新数据后,就让相应的组件产生更新?
- 下篇文章我们就会解决这个问题
最后
- 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏。
- 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰