手写实现 rc-field-form (三)

519 阅读3分钟

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

写在前面

  • 前面一篇文章,我们已经在 Form 组件之外新建了一个数据仓库
  • 这个数据仓库,用于 Form 组件的数据集中管理
  • 那我们如何让数据仓库与 React 组件之间产生联系呢?即更新数据,相应组件随即产生更新
  • 让我们往下看

实例化数据仓库对象

  • 前面已经定义了,数据仓库 FormStore 类,自然我们也需要将其实例化成一个数据仓库对象
  • 既然数据仓库管理对抗着 Form 组件的所有数据,那么数据仓库对象就应该在 Form 组件的整个生命周期类都是持续存在的
  • 那应该在哪里实例化数据仓库对象呢?
  • 基于上面的考虑,我们可以使用自定义 hook 的技巧
    • 在其内部实例化一份数据仓库对象,然后使用 useRef 将其存储起来
    • 而自定义 hook 返回的则是 useRef 中存储的数据仓库对象
    • 这样不管我们在任何地方,不管在组件的哪个生命周期内,都能通过这个自定义 hook 拿到数据仓库对象了
  • 下面是,实现的代码
export function useForm() {
  const formRef = useRef();

  if (!formRef.current) {
    const formStore = new FormStore();
    formRef.current = formStore.getForm();
  }

  return [formRef.current];
}
  • 这里做了一点点改变,还记得上篇文章实现的 getForm 方法吗
  • getForm 就是用来暴露数据仓库的相关操作方法的,返回一个数据仓库操作权限对象
  • 这样外部使用数据仓库时,只能使用 getForm 方法返回的对象所包含的操作方法,很好的解决了数据仓库的数据操作安全问题

传递数据仓库操作权限对象

  • 有了上面的 useForm 自定义 hook,我们就能在组件任意生命周期内拿到数据仓库的操作权限对象了
  • 前面说到了 Field 用于接管 Input 组件的数据输入,并从数据仓库中取出数据,传给 Input 组件进行渲染
  • 那么 Field 组件应该如何获取到数据仓库的操作权限对象呢?
  • 由于 Field 组件与 Form 组件并不一定会是父子组件关系,有可能会嵌套多层?为了保证所有的 Field 组件都能获取到同一个数据仓库的操作权限
  • 我们可以在 Form 组件上使用 useForm 获取到数据仓库的操作权限对象,然后通过 props 一层一层的传递下去
  • 但是这样未免也太不优雅了,太 low
  • 其实我们可以使用 React 提供的 Context API 进行组件的跨层级数据传递,这样就很方便了
  • 在下篇文章中,我们将实现数据仓库操作权限对象的跨层级传递

最后

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