The version corresponding to this article react
is18.2.0
How is the following dom
structure react
traversed internally?
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 > ; };
Contents
react
Internal traversal core logic:
- function
render
is called whencommitPassiveUnmountOnFiber
commitPassiveUnmountOnFiber
handle differentWorkTag
and callrecursivelyTraversePassiveUnmountEffects
recursivelyTraversePassiveUnmountEffects
Determine whether to traverse the current child node according to whether the currentFiber
child node haspassive effect
(useEffect
,, )useLayoutEffect
Fiber
- If there are child nodes
passive effect
, traverse the child nodes first (depth first) until the final leaf node is found and exit the current loop. - Then enter the sibling node and start traversing the child nodes of the sibling node
- Specifically which sibling node to start traversing from,
react
select the parent node of the leaf node that exits the loop, check whether there are any child nodes, and then traverse in a loop
- Specifically which sibling node to start traversing from,
- Until finally all
passive effect
nodes with are found
- If there are child nodes
commitPassiveUnmountOnFiber (root. current ); function commitPassiveUnmountOnFiber ( finishedWork ) { // Omitted to handle different WorkTag recursivelyTraversePassiveUnmountEffects (finishedWork); } function recursivelyTraversePassiveUnmountEffects ( parentFiber ) { // Other processing is omitted if (parentFiber. subtreeFlags & PassiveMask ) { let child = parentFiber. child ; while (child !== null ) { commitPassiveUnmountOnFiber (child);child = child.sibling ; } } }
So dom
the traversal logic for this paragraph is:
- First start from the root component
FiberRootNode
and getcurrent
- that is to say
FiberRootNode.current
isdiv#root
this is afiber
and itstag
is3
- that is to say
- Since
App
there are subcomponents ofpassive effect
, it will enterApp
the component, and itstag
is0
App
The node in the component is<div>
,<di >
oftag
is5
<div>
There are two child elements below<button>
,<A>
- The first thing to traverse
<button>
ittag
is5
<button>
There is only one text node inside, nopassive effect
- Therefore,
react
it is no longer traversed (jumps out of the current traversal loop, that is,button
this article is no longer traversed)
- Therefore,
- After jumping out of the loop, check the sibling
button
nodes<A>
of<A>
tag
0
- Since
<A>
the node has no child nodespassive effect
, it jumps out of the loop and ends the entire traversal.
Summarize
- Traverse starting from the following node
- Are there any subcomponents of the current component?
passive effect
- Take depth first
- If
dom
there is a function component in the node, thisdom
will be traversed, otherwise it will not be traversed - If there are no
fiber
children under the current , the entire linked list will not be traversed.fiber
passive effect
- These will not be traversed if there are currently
fiber
onlydom
dom
In general, don’t traverse the components to see fiber
if there are passive effect
:
- Yes, it will definitely be traversed
- No, the following two situations will be traversed, and other situations will not be traversed.
- is
passive effect
the parent component of - and
passive effect
components are siblings
- is
passive effect
Refers useEffect
,useLayoutEffect
The traversal logic is shown in the figure below
Everything with a green tick in the picture will be traversed, and the red tick is the order of traversal.