Diff algorithm classification
Diff algorithm can be divided into single-node diff and multi-node diff according to the number of child nodes
- The single-node Diff can be divided into object nodes and text nodes, depending on the node type
- For multi-node Diff, a many-to-many comparison is generally seen as a comparison between a JSX node array and a Fiber linked list
A single point of Diff
- For single-point Diff, first check to see if currentFiber is one of them
Text node
1 / / examples< p > hello </p> => Hello </
p>
// Example 2: Multiple nodes become single nodes
<div>
<p>111</p>
<p>How are you</p>
</div>= ><div>How are you</div>
Copy the code
- Updates to the text in the reconcileSingleTextNode trigger the text update method in the single nodes in the reconcileSingleTextNode, which returns the new Fiber
- Then tag the fiber with a Placement update, and the COMMIT phase will find it here and update the DOM on the page
/** * Diff for text nodes -- single-node Diff *@param {fiber} Father returnFiber fiber *@param {fiber} * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild@param {string} TextContent The text of a JSX object, whether string, number, or anything else, is first converted to string for *@param {lanes} Lanes are prioritized. */ is not used in Legacy mode
function reconcileSingleTextNode(returnFiber, curretnFirstChild, textContent, lanes) {
// In text diff, is the only one that does not need to consider keys, because there is only text, and text does not have any attribute values
if(curretnFirstChild ! = =null && curretnFirstChild.tag === HostText) {
// The current type of fiber is also Text, so we only need to compare it with this fiber. Other fibers of the same level are directly marked and deleted
deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
// Create a WIP Fiber node based on JSX's TEXT and currentFiber nodes
const existing = useFiber(currentFirstChild, textContent);
// Parent pointer points to parent fiber
existing.return = returnFiber
return existing
}
// If the first fiber does not fit, since this is text single-node Diff, regardless of the key, just delete all the old fibers and start again
deleteRemainingChildren(returnFiber, currentFirstChild);
// Create a new fiber based on the JSX text, the mode-legacy, and lanes priorities of the parent node
const created = createFiberFromText(textContent, returnFiber.mode, lanes);
created.return = returnFiber;
return created;
}
Copy the code
Element node —update
- In contrast to a text node, the element traverses all fibers of the same hierarchy looking for opportunities to change
- Element nodes rely on key alignment, then alignment by type, and finally update tags if found and return, otherwise delete currentFiberChild.
- If not, create a new fiber based on element and mount it
/** * Diff for object nodes -- single node Diff *@param {fiber} Father returnFiber fiber *@param {fiber} * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild * curretnFirstChild@param {element} ReactElement * returned from Element JSX@param {lanes} Lanes are prioritized. */ is not used in Legacy mode
function reconcileSingleElement(returnFiber, curretnFirstChild, element, lanes) {
const key = element.key
let child = curretnFirstChild
// Iterate over currentFiber and compare it to Element
// The difference between this and the text is that the text only considers the first fiber node. If not, delete all fibers of this level without giving other brothers a chance
// Here is more like a blind date, it is not appropriate to change another one and continue; Text is like if you are the One, you can only choose one, if he doesn't go with you, you go alone, nothing else.
while(! child) {// As long as the key is different, it is equivalent to different values, no matter how excellent it is
// If you don't have any values, you can look at other conditions (no key attribute).
if (child.key === key) {
// Check whether the type is consistent before and after the update
switch (child.tag) {
// case Fragment: ...
// case Block: ...
default: {
if (child.elementType === element.type) {
// This is a good idea
deleteRemainingChildren(returnFiber, child.sibling)
const existing = useFiber(child, element.props)
// ref is a special attribute and is not in props, so it needs to be handled separately
existing.ref = coerceRef(returnFiber, child, element);
existing.return = returnFiber
return existing
}
break; }}// If the key is the same and the type is different, delete all the keys and start again
deleteRemainingChildren(returnFiber, child);
break;
} else {
// If the key does not match, it is fiber
deleteChild(returnFiber, child)
}
// Switch to fiber
child = child.sibling
}
// If there is no match in fiber, the node is new
if(element.type === REACT_REACT_FRAGMENT_TYPE){
// ...
}else{
// Create a fiber based on element
const create = createFiberFromElement(element,returnFiber.mode,lane)
create.ref = coerceRef(returnFiber, child, element);
create.return = returnFiber
return create
}
}
Copy the code
instructions
- Series of texts are mainly achieved
Output forces input
The purpose, but the principle may have lost lost understand, look at the source code to spend more time, so a single problem in detail after time is almost yao got. - So a single problem may be more days, this is also helpless, after all, the ability is limited, if there is a small partner also look at the source, explore his specific implementation, can discuss together, guidance guide me
- Day is the habit of forming, not only the output of the article, but also includes a series of input learning, thinking, persistence and so on. When there is not enough time, it may only break the chapter, and the subsequent single problem will be summarized, so that it will be perfect.
- I hope I can get up early every day, learn every day, think every day, update every day, come on.