React 表单设计 及 通用模式、组件抽取

发布于 2022-04-24 12:48:10 字数 3172 浏览 1120 评论 0

React 表单设计

一份表单设计,其他涉及众多的细节。如果单独处理,无疑什么繁琐,充满众多细节。而其实上,作为「填表单」这个行为,它定制的部分却往往不多,比如使用者只需要关注「验证逻辑」、「显示什么错误信息」等高层的东西,而底层的行为和细节代码我们希望不需要过多关注。这样,「表单」就具有了一些逻辑上的共性,可以把这些东西抽取出来,封装成为组件,然后让使用者只需要关注高层的东西(逻辑、错误信息、验证方式等)。

基于这个考虑,「表单填写」这个场景有哪些细节需要考虑呢?不同的细节决定了怎样不同的技术实现方式呢?高层需要考虑的东西可以简化成什么呢?

基本问题

  • 支持表单纯净性检查(pristine)
  • 支持基本的验证功能(validation callback): f(data) => errorMessage
  • 支持基本的提交表单时验证功能(submit)
  • 支持传出表单当前状态(已填数据、错误信息)

更细节问题

  • 是否需要支持错误信息精确到字段级别?这可能有几种场景,但基本都是一个字段的(业务)合法性不能在填写当时验证(需要结合其他数据进行验证):
    • 比如在填 B 字段的时候需要 A 字段数据,此时校验发现 A 字段是业务错误的,那么需要将字段 A 标红
    • 比如在提交整个表单的时候发现 A 字段业务不合法,提示错误信息,并将其标红
  • 是否需要支持字段的异步(后端)验证?提交时进行后端这是可以理解的,问题是字段级别是否也需要进行异步验证?这会关系到组件设计和应用架构的问题(错误信息是在哪管理,api 在哪里调用)

技术支持

下面谈谈这几种场景所需要的解决方案。

  • pristine 纯净性检查:很简单。默认内置支持即可
  • 基本的验证功能:很简单,提供一个 onValidate 即可,因为这里需要支持定制化的点就是这个 validator:validate(data) => errorMessage。它需要实现这个契约
  • 基本的提交表单时验证功能:很简单,提供一个 onSubmit 方法即可,这也是需要支持定制化的点
  • 基本的表单当前状态维护:很简单,提供一个什么接口传出来即可。什么时候需要数据就什么时候传出来,错误信息同理
  • 支持字段级别的错误定位:这个需要提供一个表单级别的 wrapper,由它来管理所有字段所产生的 error,由于有不同字段,肯定又需要 key 来区分,因此,这个从技术上需要两个东西:
    • 提供 Form 表单级别的组件,它会通过某种契约知晓、控制组件之间的状态(显示、错误信息、数据、是否禁用等)
    • 提供 Field 字段级别的组件,它需要实现某种契约,与 Form 组件通晓状态

比较难缠的是字段的异步(后端)验证这个问题。一般来说,表单的验证分为两种,一种是表单级别的验证,这种验证一定要通过后端验证;另一种是字段级别的验证,这种验证既可以使用前端验证,也可以使用后端验证。

其中,字段的前端验证,其实就是前面提供的 onValidate 接口,该种验证是同步完成的,通常速度极快,多只是校验表单数据是否为空,长度是否过长等「格式」上的问题。这种验证方式下,出错信息可以直接反映到字段上,通常来说,出错信息也是存储在组件的 state 中即可。

为字段验证带来挑战的是后端验证方式。由于需要走一趟后端,所以必然要调一趟 API,再从 API 的结果来确定是否有出错信息、出错信息是什么。而一般而言,我们的出错信息是在组件的 state 中管理的,而一般来说 API 作为有副作用的行为,发生地都在 redux/saga 中,最后必然是从 props 这种进来。那么,如何管理这两个不同的数据源?策略无外乎三种:

  • 统一数据源到组件内部 state。这使得 API 必须写到组件内部,而非 thunk/saga 等专门管理的工具,不利于架构可追溯状态的应用,一定程度上违背了 react/redux 应用的架构和设计原则
  • 统一数据源到 redux 并作为 props 使用。这解决了上一点的架构问题,但使得本来非常简单的 字段前端验证 校验也必须放到 redux 中做,使这部分校验变重了,也失去了一些可读性
  • 不统一数据源,组件接受 props 和 state 产生的错误信息。这样必须还必须在组件内部「以某种形式管理」这两份错误信息,而这个管理方式就需要使用者来定制,并且还需要知道本来仅由 Validator 管理的 error message 的细节及其契约,API 就很不友好,也非常不组件化

API

综上,作为表单的设计者,在获得一个满意的解决方案前,你需要问自己,自己的表单复杂性有多高?是否需要支持字段级别的后端验证?是否需要支持跨字段的验证?是否需要定制 UI?有了确定的答案后,你才能知道这个表单需要什么技术支持、是否需要引入三方库,以及如何选择合适的三方库等。

三方库

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文