借助 valtio 为 react function component 添加 this (实际为 self)
React Class component 比较方便的一点是基于 class 和 instance, 可以保存一些状态到实例(this.state)上, 但 FC + hooks 心智负担更小, 已全面替代 class component. 但需要不停地 useState / useRef, 有没有可能也用上 this 呢?
演示 1 2 3 function Foo ( ) { return <div > the Foo Component</div > }
借助 valtio 创建 FC 伴生类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { proxy, useSnapshot } from 'valtio' class FooSelf { store = proxy ({ state1 : true , items : [] as string [], }) someProp = false useStore = () => { return useSnapshot (this .store ) } setStore = (payload: Partial<typeof this .store> ) => { Object .assign (this .store , payload) } }
需要参与渲染的状态如 state1 items 等, 放到 FooSelf.store, 就像 class component this.state 一样
不需要参与渲染的状态如 someProp, 放到 class property 上即可, 心智模型与 class compoennt 的 class property 或 FC useRef 一致.
useInitFooSelf1 2 3 4 5 6 7 8 9 10 11 12 function useInitFooSelf ( ) { const ref = useRef (null ) ref.current ||= new FooSelf () return ref.current } import { useCreation } from 'ahooks' function useInitFooSelf ( ) { return useCreation (() => new FooSelf (), []) }
useRef 不支持 factory method, 只能这样处理
或使用现成库
使用 1 2 3 4 5 function Foo ( ) { const self = useInitFooSelf () const { state1, items } = self.useStore () return <div > the Foo Component</div > }
这样可以
减少很多 useState / useRef 代码
使用 self.useStore 获取渲染状态, 使用 self.store.<prop> 读取最新状态, 设置状态用 self.setStore() , 心智模型类似 this.setState
可以方便 lift state up, 比如使用 React Context FooSelfContext, 将整个 fooSelf 共享给子树