> 之前在研摩完 https://github.com/react-hook-form/react-hook-form 后感叹到前端的设计理念博大精深,但是一直没有整理,这两天考试周回校有空整理了一下
前有数据驱动视图的 Vue 和 React ,现在到了特殊场景又要具体分析开发的视图驱动数据的 useForm
业务情景:当一个大表单的局部字段变更时,普通 React 会直接 re-render 整个大表单导致性能耗散,最优解是尽量避免重渲染
useForm的内部可以理解为:
当用户 input 的时候 register 捕获事件,向内写入到 formValues 并更新 formState ,接着 subjects 通过观察者模式遍历广播变更,仅订阅了这些 subjects 的 hooks 会调用 useState ,从而触发最小范围的 Fiber 调度
而普通的 input 做了特判完全不会触发 re-render
[用户输入]
↓ (onChange)
register -> handleChange
↓
更新 _formValues
↓
_subjects.watch.next({ name, value }) // 发布事件
↓
useWatch/useFormState/useController 订阅回调
↓
setState(...)
↓
React Fiber 调度(仅局部组件)
需要注意,这里的观察者模式并不像 Vue 那样去挟持属性实现响应化( Vue2 的 Object.defineProperty 和 Vue3 的 Proxy ),而是其内部自己维护了一个 subjects ,从而避免像 Vue 一样自动更新视图,遵循 React 的显式思维去广播变更,触发局部的 Fiber 调度