7

React 根据状态动态化功能的一些思考

 3 years ago
source link: https://blog.rxliuli.com/p/12f1321e/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

React 根据状态动态化功能的一些思考

之前吾辈也在 SF 上询问过 类似的问题

目前在实际业务中遇到了两种情况

  1. 程序的功能在分发给不同组织使用的时候有所差异,即不同的组织都会存在一些定制化的功能。
    最常见的差异例如
    • 表单的字段存在差异
    • 列表展示的字段与相关操作有所不同
  2. 组件内的代码在某个权限下才会执行,但是又依赖于组件内的一些状态,如何将这些代码分割到不同的地方(例如不同的文件)便于之后的维护。
    • 一些按钮在指定权限下存在
    • 一些数据在指定权限下展示
  • 使用动态配置渲染不同的页面(可序列化的配置)
  • 根据状态匹配不同的动态组件
  • 使用 hooks 封装不同的逻辑

实际调研结果

使用动态配置渲染不同的页面

实际上,之前有看过吾辈写的 react 通用列表组件封装 就知道,实际上列表已经被配置化了,可以使用配置的形式去渲染一个完整的列表页面,因此可以根据不同的组织使用不同的配置就好了。但是,事实上并没有这么简单,因为就算是简单的列表,也仍然包含上下文,而这,正是配置不能拿到的内容。

上下文主要包括

  • 需要异步请求的数据,例如下拉框的选择项
  • 需要从路由上获取的数据,例如搜索条件
  • 需要对页面内的其它组件进行操作时,例如点击按钮有个新增列表项的弹窗

可以有几种解决方案

  • 通过函数,而不是单纯的配置,这样,可以通过参数解决一些上下文的依赖情况
  • 通过函数且异步,可以解决 api 请求时,此时的 api 必定是可以用的,但是会依赖于 api。

但这仍然会带来问题

  • 数据不再纯粹,无法序列化。
  • 不同配置依赖的数据可能不同,需要配置自己去解决,那么如果这样想的话,那么配置就需要自行获取数据,而不是外部传递数据了
  • 仍然无法使用状态
  • 最重要的是,使用函数之后变得不再像是配置

根据状态匹配不同的动态组件

  • 配置更为灵活,能够获取到组件的上下文
  • 接口请求也没有问题
  • 对不同配置,可以自行对数据进行处理
  • 无法如同纯数据配置那样,复用逻辑这么彻底,但是也可以通过 hooks 解决。
  • UI 复用问题
    先使用组件的方式编写一下,看具体结果如何
  • 无法序列化也意味着无法放到后端,甚至意味着很难做动态加载
  • 使用一个 wrapper 组件来讲 UI 和通用逻辑给包裹进去
  • 使用另外一套组件去区分不同租户的配置(因为是在组件内部写配置,所以该配置可以灵活的使用任意接口,组件上下文可能还不太行)也就是用多个组件来解决这个问题。

可以再尝试一下有没有解决方案。

使用 hooks 封装不同的代码

  • 相比于处理 是哪一个,更适合处理 有或没有 的代码分割
  • 能够使用 react 的状态
  • 使用 hooks 必须放在函数组件最顶层,导致本质上无法 lazy 加载。参考:Hook 规则
  • 使用 hooks 同样难以序列化存储到后端

最终,我们选择了最灵活的 动态组件 + Hooks 共享逻辑 的形式,虽然使用动态组件会增加一些冗余度,但也可以通过子组件或 hooks 的形式复用逻辑,实际上在工程化减小的复杂度的收益是要高于代码冗余的。

登记相关内容已经使用该方式进行了重构

  • src/pages/register
    • common: 通用的一些组件和逻辑,例如请求后台接口应该是统一的,但返回的数据类型却应该是单独的
      • form: 表单相关组件,提供给列表/详情页面使用
      • detail: 详情页面
      • list: 列表页面
    • organizations: 不同组织的目录
      • org1: 组织 1
      • org2: 组织 2

吾辈编写了一个简单的示例,代码在 dynamic_state

简单示例

其他技术问题

  • 如何在运行时根据组织切换功能
    • 可以再包一层组件而非简单的从 lazy component map 取出组件
  • 如何在运行时添加新组织的功能
    • 可能需要插件的实现方式,支持动态加载进来,例如 vscode 的插件体系。
  • 如何使用 hooks 更好的复用逻辑
    • 使用 hooks 封装逻辑,使用小型组件封装 UI/UX
  • 如何在打包阶段干掉不相关组织的代码
    • 需要修改 webpack 相关的内容,目前不予考虑

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK