react如何实现hooks?必须依赖 Fiber 么?( 二 )


因为它主要考虑的是体积的极致(只有 3kb) , 而不是性能的极致 。

react如何实现hooks?必须依赖 Fiber 么?

文章插图

刚才我们了解了 react 是把 hook 链表存放在 fiber 节点上的 , 那 preact 没有 fiber 节点 , 会把 hook 链表存在哪呢?
其实也很容易想到 , fiber 只是对 vdom 做了下改造用于提升性能的 , 和 vdom 没啥本质的区别 , 那就把 hook 存在 vdom 上不就行了?
确实 , preact 就是把 hook 链表放在了 vdom 上 。
比如这个有 4 个 hooks 的函数组件:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

【react如何实现hooks?必须依赖 Fiber 么?】它的实现就是在 vdom 上存取对应的 hook:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

react如何实现hooks?必须依赖 Fiber 么?

文章插图

它没有像 react 那样把 hook 分为 mount 和 update 两个阶段 , 而是合并到一起处理了 。
如图 , 它把 hooks 存在了 component.__hooks 的数组上 , 通过下标访问 。
这个 component 就是 vdom 上的一个属性:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

也就是把 hooks 的值存在了 vnode._component._hooks 的数组上 。
对比下 react 和 preact 实现 hooks 的差异:
    react 中是把 hook 链表存放在 fiberNode.memorizedState 属性上 , preact 中是把 hook 链表存放在 vnode._component._hooks 属性上
    react 中的 hook 链表通过 next 串联 , preact 中的 hook 链表就是个数组 , 通过下标访问
    react 把 hook 链表的创建和更新分离开 , 也就是 useXxx 会分为 mountXxx 和 updateXxx 来实现 , 而 preact 中合并在一起处理的
所以说 , hooks 的实现并不依赖 fiber , 它只不过是找个地方存放组件对应的 hook 的数据 , 渲染时能取到就行 , 存放在哪里是无所谓的 。
因为 vdom、fiber 和组件渲染强相关 , 所以存放在了这些结构上 。
像 react ssr 实现 hooks , 就既没有存在 fiber 上 , 也没有存在 vdom 上:
react ssr 如何实现 hooks其实 react-dom 包除了可以做 csr 外 , 也可以做 ssr:
csr 时使用 react-dom 的 render 方法:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

ssr 的时候使用 react-dom/server 的 renderToString 方法或 renderToStream 方法:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

大家觉得 ssr 的时候会做 vdom 到 fiber 的转换么?
肯定不会呀 , fiber 是为了提高在浏览器中运行时的渲染性能 , 把计算变成可打断的 , 在空闲时做计算 , 才引入的一种结构 。
服务端渲染自然就不需要 fiber 。
不需要 fiber 的话 , 它把 hook 链表存放在哪里呢?vdom 么?
确实可以放在 vdom , 但是其实并没有 。
比如 useRef 这个 hooks:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

它是从 firstWorkInProgressHook 开始的用 next 串联的一个链表 。
react如何实现hooks?必须依赖 Fiber 么?

文章插图

而 firstWorkInProgressHook 最开始用 createHook 创建的第一个 hook 节点:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

并没有挂载到 vdom 上 。
为什么呢?
因为 ssr 只需要渲染一次呀 , 又不需要更新 , 自然没必要挂到 vdom 上 。
只要每次处理完每个组件的 hooks 就清空一下这个 hook 链表就行:
react如何实现hooks?必须依赖 Fiber 么?

文章插图

react如何实现hooks?必须依赖 Fiber 么?

文章插图

react如何实现hooks?必须依赖 Fiber 么?

文章插图

所以 , react ssr 时 , hooks 是存在全局变量上的 。
对比下 react csr 和 ssr 时的 hooks 实现原理的区别: