从 0 开始手写 rc-form(三)

8,051 阅读3分钟

「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战」。

写在前面

  • 前面我们已经实现了 createForm 的部分功能,如
    • 使用 getFieldDecorator 方法进行数据输入的接管,
    • 使用 createForm 所返回的新组件的 state 去集中管理输入的数据
  • 然后我们又写了一个 demo 去验证我们实现的功能
  • 今天这篇文章,我们将继续完善 createForm 的功能,并在 demo 中去验证
  • 前面也提到了,我们想要实现的功能有以下三点
    • 接管用户数据的输入,并统一管理输入的数据
    • 校验输入的数据的正确性
    • 提交数据
  • 接下来我们就开始实现 校验输入的数据 的功能

校验数据

  • 如何校验数据呢?需要内置在 createForm 中吗?
  • 校验数据比较特殊,只有使用 createForm 的开发者才知道自己想要校验哪些数据,以及如何校验这些数据,因此我们不能将校验规则内置在 createForm 中,而应该由外部输入
  • 下面是校验规则,应该放在我们上篇文章的 demo 中
const rules = {
  user: { required: true, message: "请输入用户名!" },
  pwd: { required: true, message: "请输入密码!" },
};
  • 那么问题又来了,我们为了校验数据,肯定需要实现一个 validateFields 方法,那么在如何在 validateFields 中使用 rules 呢?
  • 我们可以在 getFieldDecorator 方法将 rules 传入,然后存起来,validateFields 需要使用时,直接获取即可,下面是代码实现:
    • 首先改写 demo 中的 renderField 方法,将对应的 数据输入组件的 rules 传入 getFieldDecorator
renderField = (type) => {
    const { form } = this.props;

    return form.getFieldDecorator(type, { rules: [rules[type]] })(
      <Input placeholder={type} />
    );
};
- 接下来修改 getFieldDecorator,将传入的校验规则存在 createForm 返回的组件实例上的 options 属性上
    constructor(props) {
      super(props);

      this.state = {};

      this.options = {};
    }
    
    getFieldDecorator = (fieldName, option) => (FieldCom) => {
      this.options[fieldName] = option;

      return React.cloneElement(FieldCom, {
        name: fieldName,
        value: this.state[fieldName],
        onChange: this.onChange,
      });
    };
  • 最后我们就可以顺利实现 validateFields 方法了
    validateFields = (callback) => {
      const err = [];

      // 这里默认只校验:值是否为空的情况
      for (const fieldName in this.options) {
        if (!this.state[fieldName]) {
          err.push({ [fieldName]: this.options[fieldName].rules[0].message });
        }
      }

      const res = { value: this.state };
      if (err.length) {
        res.err = err;
      }

      callback(res);
    };
  • validateFields 方法接收一个回掉函数,当校验完毕之后,执行回掉函数,将校验的结果传给回掉函数
  • 这里的校验只是简单实现了数据必填的规则,理论上应该遍历 options 中的所有校验规则,然后对相应的数据进行校验,这才严谨,有兴趣的小伙伴可以自行完善这部分逻辑

小结

  • 至此,我们就实现完了 validateFields 方法,createForm 的数据校验的相关逻辑已经实现
  • 下篇文章,我们将实现数据的提交逻辑,同时并校验 validateFields 的可用性

最后

  • 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏。
  • 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰