Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the Node deletion algorithm of React and DOM

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article focuses on "how to use React and DOM node deletion algorithm", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to use the node deletion algorithm of React and DOM.

Fiber architecture makes React need to maintain two kinds of tree structure, one is Fiber tree, the other is DOM tree. When the DOM node is deleted, the Fiber tree changes synchronously. However, please pay attention to the timing of the deletion operation: delete the DOM node before completing other changes (additions and modifications) of the fiber node to prevent other operations from being interfered with. This is because the fiber tree needs to be looped when performing other DOM operations, and confusion will occur if there are fiber nodes that need to be deleted but have not been deleted.

Function commitMutationEffects (firstChild: Fiber, root: FiberRoot, renderPriorityLevel,) {let fiber = firstChild; while (fiber! = = null) {/ / first delete const deletions = fiber.deletions; if (deletions! = = null) {commitMutationEffectsDeletions (deletions, root, renderPriorityLevel) } / / if the deleted fiber still has child nodes, / / Recursively call commitMutationEffects to handle if (fiber.child! = = null) {const primarySubtreeTag = fiber.subtreeTag & MutationSubtreeTag; if (primarySubtreeTag! = = NoSubtreeTag) {commitMutationEffects (fiber.child, root, renderPriorityLevel) }} if (_ _ DEV__) {/ *... * /} else {/ / perform other DOM operations try {commitMutationEffectsImpl (fiber, root, renderPriorityLevel);} catch (error) {captureCommitPhaseError (fiber, error);}} fiberfiber = fiber.sibling;}}

Fiber.deletions is the diff process of the render phase that detects that child nodes of fiber will be added here if they need to be deleted.

The commitDeletion function is the entry to delete the node, which is deleted by calling unmountHostComponents. Before you understand the delete operation, take a look at the scene.

With the following Fiber tree, the Node (Node is a code name, does not refer to a specific node) node is about to be deleted.

Fiber tree div#root | | div | | Node | ↖ | ↖ P-> | a

From this scenario, it can be inferred that when the node is deleted, all nodes in its underlying subtree will be deleted. Now take this scenario as an example and go through the deletion process. This process is actually the mechanism by which the unmountHostComponents function runs.

Delete process

Deleting a Node node requires the participation of the parent DOM node:

ParentInstance.removeChild (child)

So first navigate to the parent node. The process is to look up from the parent node of the Node in the Fiber tree, and the first native DOM node found is the parent node. In this example, the parent node is div. After that, we traverse the subtree with Node as the starting point, and the subtree is also the fiber tree, so traversal is depth-first, deleting each child node.

It is important to note that when the loop node is deleted, each node is processed by the delete operation, where each node is a fiber node rather than a DOM node. The time to delete a DOM node is when you start traversing the Node for deletion, and when you encounter the first native DOM node (HostComponent or HostText), it will not be deleted until all fiber nodes in its subtree are deleted.

The above is a brief description of the complete process, for the detailed process, it is necessary to clarify the responsibilities and calling relationships of several key functions. The fiber node is deleted by the unmountHostComponents function, and the deleted node is called the target node, and its responsibilities are as follows:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Find the parent node of the DOM level of the target node

Determine if the target node is a native DOM type node, then execute 3 and 4, otherwise uninstall yourself first and then go down to find the native DOM type node and then execute 3 and 4

Traversing the subtree to unload the fiber node

Delete the DOM node of the target node

The third step, which is done through commitNestedUnmounts, has a single and clear responsibility, which is to unload nodes through the subtree.

Then specific to the uninstall process of each node, which is completed by commitUnmount. Its duty is

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Uninstall Ref

Invocation of the life cycle of a class component

The fiber node of HostPortal type recursively calls the unmountHostComponents repeated deletion process

Let's take a look at the specific deletion process for different types of components.

Distinguish the categories of deleted components

There are many possibilities for the types of Node nodes. Let's take the three most typical types (HostComponent, ClassComponent, HostPortal) as examples to illustrate the deletion process.

First, unmountHostComponents is executed, and the parent node of the DOM level is found up, and then processed separately according to the following three component types, which we will look at one by one.

HostComponent

Node is HostComponent, call commitNestedUnmounts, traverse the subtree with Node as the starting point, and start unloading all child Fiber. The traversal process is depth-first traversal.

Delation-- > Node (span) | ↖ | ↖ P-> | a

Uninstall the commitUnmount one by one, and this traversal process is similar for all three types of nodes. To save space, it is only described once here.

The fiber of Node is uninstalled, then down, the fiber of p is uninstalled, p has no child, the sibling is found, the fiber is uninstalled, and the fiber of amema is uninstalled. At this point, you get to the leaf node of the entire subtree and start return up. From a to, then back to Node, traversing the uninstall process ends.

Only after all fiber nodes of the subtree are uninstalled can the DOM node of the Node be safely removed from the parent node.

ClassComponent

Delation-- > Node (ClassComponent) | | span | ↖ | ↖ P-> | a

Node is ClassComponent, and it does not have a corresponding DOM node. You need to call commitUnmount to uninstall itself, and then you will first look down to find the first native DOM node, span, and use it as a starting point to traverse the subtree to ensure that each fiber node is uninstalled, and then delete the span from the parent node.

HostPortal

Div2 (Container Of Node) ↗ div containerInfo | ↗ | ↗ Node (HostPortal) | | span | ↖ | ↖ P-> | a

Node is HostPortal, and it does not have a corresponding DOM node, so the deletion process is basically the same as ClassComponent, except that when deleting the DOM node of the first child fiber below it, it is not deleted from the parent node of the DOM level of the deleted HostPortal node, but is removed from the containerInfo of HostPortal. It is div2 on the diagram, because HostPortal renders the child node to a DOM node other than the parent component.

The above is the process of deleting three types of nodes. It is worth noting here that when the unmountHostComponents function uninstalls each node through the subtree, once it encounters a child node of type HostPortal, it will call unmountHostComponents again, and uninstall and delete it and its subtree with it as the target node, which is equivalent to a recursive process.

CommitUnmount

CommitUnmount is called for both HostComponent and ClassComponent deletions, and FunctionComponent also calls it. It works differently for three components:

Once useEffect is called in the FunctionComponent function component, it calls the destroy function of useEffect when it is uninstalled. (the destroy function of useLayoutEffect is executed by calling commitHookEffectListUnmount.)

The ClassComponent class component calls componentWillUnmount

HostComponent wants to uninstall ref

Function commitUnmount (finishedRoot: FiberRoot, current: Fiber, renderPriorityLevel: ReactPriorityLevel,): void {onCommitUnmount (current); switch (current.tag) {case FunctionComponent: case ForwardRef: case MemoComponent: case SimpleMemoComponent: case Block: {const updateQueue: FunctionComponentUpdateQueue | null = (current.updateQueue: any); if (updateQueue! = = null) {const lastEffect = updateQueue.lastEffect If (lastEffect! = = null) {const firstEffect = lastEffect.next; let effect = firstEffect; do {const {destroy, tag} = effect If (destroy! = = undefined) {if ((tag & HookPassive)! = = NoHookEffect) {/ / to push effect enqueuePendingPassiveHookEffectUnmount (current, effect) in the destroy function queue of useEffect;} else {/ / attempt to call destroy safelyCallDestroy (current, destroy) using try...catch ...} effecteffect = effect.next;} while (effect! = = firstEffect);}} return;} case ClassComponent: {safelyDetachRef (current); const instance = current.stateNode / / call componentWillUnmount if (typeof instance.componentWillUnmount = = 'function') {safelyCallComponentWillUnmount (current, instance);} return;} case HostComponent: {/ / uninstall ref safelyDetachRef (current); return;}.}}

Summary

Let's review the key points in the deletion process:

When the delete operation is performed

Who is the target of deletion?

Where to delete

Mutation needs to delete the node before doing other operations on the DOM based on the Fiber node to ensure that the fiber nodes left for subsequent operations are valid. The target of deletion is the Fiber node and its subtree and the DOM node corresponding to the Fiber node. The whole trajectory follows the fiber tree, uninstalls the target node and all child nodes, and deletes the corresponding (or the first below) DOM node of the target node. For a native DOM node, it is deleted directly from its parent DOM node, and for a HostPortal node, it renders the child node to an external DOM node, so it is deleted from this DOM node. A clear understanding of the above three points and combined with the above carding process can gradually clarify the context of the deletion operation.

At this point, I believe you have a deeper understanding of "how to use React and DOM node deletion algorithm". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report