#yyds干货盘点#React多节点 diff 原理
  Qp5JTyIxtbwu 2023年11月02日 17 0

在 React 中,通过 React.createElement 能生成一个虚拟 DOM 节点(ReactElement)。在 React15 及以前,采用了递归的方式创建虚拟 DOM,递归过程是不能中断的。如果组件树的层级很深,递归会占用线程很多时间,造成卡顿。React16 将递归的无法中断的更新重构为异步的可中断更新,推出了新的 Fiber 架构。

原本的 ReactElement 只有 children,在中断恢复时,无法找到其兄弟节点和父节点,无法从断点处继续完成渲染工作。而 fiber 节点上能访问到父节点、子节点、兄弟节点,所以即使渲染被打断了,也可以恢复查找未处理的节点。因此,React 需要先生成 ReactElement,再生成 fiber,最后才将变更映射到真实 DOM 节点。这一点和 Vue 有很大不同。

React 采用了双缓存的技术,在 React 中最多会存在两颗 fiber 树,当前屏幕上显示内容对应的 fiber 树称为 current fiber 树,正在内存中构建的 fiber 树称为 workInProgress fiber 树。当 workInProgress fiber 树构建并渲染到页面上后,应用根节点的 current 指针指向 workInProgress Fiber 树,此时workInProgress Fiber 树就变为 current Fiber 树。

假设我们有这样一段代码:

const App = () => {
  const [count, setCount] = React.useState(0)
  return <div onClick={() => setCount(n => n + 1)}>{count}</div>
}

ReactDOM
  .createRoot(document.getElementById('root'))
  .render(<App />)

React 的更新会经历两个阶段:render 阶段 和 commit 阶段。render 阶段是可中断的,commit 阶段是不可中断的。

render 阶段会生成 fiber 树,所谓的 diff 就会发生在这个阶段。React 通过深度优先遍历来生成 fiber 树,整个过程与递归是类似的,因此生成 fiber 树的过程又可以分为「递」阶段和「归」阶段。

commit 阶段主要执行各种 DOM 操作、生命周期钩子、某些 hook 等。

因此,diff 阶段不会直接变更 DOM,而是留到 commit 阶段再做变更。



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: CAS—认证原理 下一篇: CORS简介 跨域
  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
Qp5JTyIxtbwu