这篇文章主要介绍“怎么掌握React组件树遍历技巧”,在日常操作中,相信很多人在怎么掌握React组件树遍历技巧问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么掌握React组件树遍历技巧”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
引言
本文对应的 react
版本是 18.2.0
下面的 dom
结构react
内部是如何遍历的
const App = () => { return ( <div> <button>+1</button> <A count={0} /> </div> );};const A = (props) => { useEffect(() => { console.log(props.count); }, [props.count]); return <div>{props.count}</div>;};
react 内部遍历核心逻辑:
在
render
时调用commitPassiveUnmountOnFiber
函数commitPassiveUnmountOnFiber
处理不同的WorkTag
,并调用recursivelyTraversePassiveUnmountEffects
recursivelyTraversePassiveUnmountEffects
根据当前Fiber
的子节点有没有passive effect
(useEffect
,useLayoutEffect
)来决定是否遍历当前Fiber
的子节点具体从哪个兄弟节点开始遍历,
react
选择的是离退出循环的那个叶子节点的父节点,检查有没有子节点,以此循环遍历如果子节点有
passive effect
,则优先遍历子节点 (深度优先),直到找到最终的叶子节点,退出当前循环然后进入兄弟节点,开始遍历兄弟节点的子节点
直到最后找到所有有
passive effect
的节点
代码简化:
commitPassiveUnmountOnFiber(root.current);function commitPassiveUnmountOnFiber(finishedWork) { // 省略了处理不同的 WorkTag recursivelyTraversePassiveUnmountEffects(finishedWork);}function recursivelyTraversePassiveUnmountEffects(parentFiber) { // 省略了其他处理 if (parentFiber.subtreeFlags & PassiveMask) { let child = parentFiber.child; while (child !== null) { commitPassiveUnmountOnFiber(child); child = child.sibling; } }}
所以对于这段 dom 的遍历逻辑是:
首先从根组件开始
FiberRootNode
,取到current
也就是说
FiberRootNode.current
是div#root
这是一个fiber
,它的tag
是3
由于
App
的子组件有passive effect
,所以会进入App
组件,它的tag
是0
App
组件中节点是<div>
,<di >
的tag
是5
<div>
下面有两个子元素<button>
、<A>
先遍历
<button>
它的tag
是5
<button>
内部只有一个文本节点,没有passive effect
所以
react
不遍历了(跳出当前遍历的循环,也就是button
这条不在遍历了)跳出循环后,查看
button
的兄弟节点,它的兄弟节点是<A>
,<A>
的tag
是0
由于
<A>
节点的子节点没有passive effect
,所以跳出循环,结束整个遍历
遍历逻辑如下图所示
图中画绿色勾的都会被遍历,红色勾是遍历的顺序
到此,关于“怎么掌握React组件树遍历技巧”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!