React Fiber structure creation steps

React Fiber structure creation steps

React Fiber Creation

The current React version is based on V17.0.2. This article mainly introduces the creation of the fiber structure.

1. Before you begin

This is my personal understanding. If there is anything wrong, please point it out.

First, you need to configure the React debugger development environment. The entry is here: github

Execute npm run i to install dependencies and npm start to run the environment.

2. Start with React.render

By calling React.render at the project entry, turn on Debug and view the React call stack.

const root = document.getElementById('root');
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  root
);

After React calls render, it calls legacyRenderSubtreeIntoContainer after passing in the base configuration.

export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function,
) {
  // Remove some environment code // ...
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

After React calls render, it calls legacyRenderSubtreeIntoContainer after passing in the base configuration.

export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function,
) {
  // Remove some environment code // ...
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

legacyRenderSubtreeIntoContainer does two things in total: one is to generate fiberRoot, the other is to call updateContainer.

Enter the legacyCreateRootFromDOMContainer function to see how to generate fiberRoot. Inside the function, createLegacyRoot is called, and here we distinguish whether to use hydrate, as follows:

  return createLegacyRoot(
    container,
    shouldHydrate
      ? {
        hydrate: true,
      }
      : undefined,
  );

For createLegacyRoot, it is used to instantiate the ReactDOMLegacyRoot function. Through subsequent calls, it finally enters the generation of root, calls the createRootImpl function, and instantiates the root.

Enter the createFiberRoot function and initialize FiberRootNode.

function FiberRootNode(containerInfo, tag, hydrate) {
  this.tag = tag; // type this.containerInfo = containerInfo; // container
  this.pendingChildren = null; 
  this.current = null;
  this.pingCache = null;
  this.finishedWork = null;
  this.timeoutHandle = noTimeout;
  this.context = null;
  this.pendingContext = null;
  this.hydrate = hydrate;
  this.callbackNode = null;
  this.callbackPriority = NoLanePriority;
  this.eventTimes = createLaneMap(NoLanes);
  this.expirationTimes = createLaneMap(NoTimestamp);

  this.pendingLanes = NoLanes;
  this.suspendedLanes = NoLanes;
  this.pingedLanes = NoLanes;
  this.mutableReadLanes = NoLanes;
  this.finishedLanes = NoLanes;

  this.entangledLanes = NoLanes;
  this.entanglements = createLaneMap(NoLanes);

  // ....


}

There are several types of tags here.

export type RootTag = 0 | 1;

The above structure is the fiberRootNode node.

When rootTag is equal to 0, it represents legacy rendering mode, and when it is equal to 1, it represents Concurrent mode rendering. That is to say, traditionally we use React.render for rendering, and when React.createRoot is called, it enters Concurrent mode rendering mode, that is, parallel rendering.

Now let's take a look at the structure of the fiber.

  const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride);
  root.current = uninitializedFiber;
  uninitializedFiber.stateNode = root;

uninitializedFiber is the instance of the created FiberNode.

const createFiber = function(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
): Fiber {
  // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
  return new FiberNode(tag, pendingProps, key, mode);
};

Through basic creation, the FiberNode structure is generated as follows

function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // Instance
  this.tag = tag; //component type this.key = key; //key attribute this.elementType = null; //element type, class function, display class, div display div
  this.type = null; //func or class
  this.stateNode = null; //dom node // Fiber
  this.return = null; //Points to the parent node this.child = null; //Points to the child node this.sibling = null; //Sibling node this.index = 0; //

  this.ref = null;

  this.pendingProps = pendingProps; // Waiting for properties pendingProps
  this.memoizedProps = null; //Memory properties, usually store props
  this.updateQueue = null; //Update queue this.memoizedState = null; //Generally store state
  this.dependencies = null;

  this.mode = mode;

  // Effects related this.flags = NoFlags;
  this.subtreeFlags = NoFlags;
  this.deletions = null;

  this.lanes = NoLanes;
  this.childLanes = NoLanes;

  this.alternate = null; //points to workInProgress
}

The basic display of FiberNode is as above. The basic types of elementType and type are function and class.

By comparing the fiberRootNode structure with the following code, the final FiberNode structure is generated.

render() {
    const { name, count } = this.state;
    return (
      <div className="App">
          <Button name={name} />
        {
          count
        }
      </div>
    );
  }
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  root
);

Through the final execution, the fiberRoot linked list structure is generated.

Finally, unbatchedUpdates is called for rendering.

Enter the updateContainer function.

unbatchedUpdates(() => {
  // Update container
  updateContainer(children, fiberRoot, parentComponent, callback);
});

3. End

The above are the details of the steps to create the React Fiber structure. For more information about the creation of the React Fiber structure, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • A detailed explanation of how React Fiber works

<<:  How to deal with the prompt "Operation not permitted" when deleting files in Linux

>>:  Detailed explanation of the implementation method of database multi-table connection query

Recommend

Invalid solution when defining multiple class attributes in HTML

In the process of writing HTML, we often define mu...

Examples of two ways to implement a horizontal scroll bar

Preface: During the project development, we encou...

The process of installing Docker in Linux system

In this blog, I will walk you through the process...

CSS shadow animation optimization tips

This technique comes from this article - How to a...

Detailed explanation of vue.js dynamic components

:is dynamic component Use v-bind:is="compone...

Make your website run fast

Does performance really matter? Performance is im...

Two ways to correctly clean up mysql binlog logs

mysql correctly cleans up binlog logs Preface: Th...

Detailed explanation of the use of MySQL group links

Grouping and linking in MYSQL are the two most co...

Detailed explanation of docker compose usage

Table of contents Docker Compose usage scenarios ...

MySQL Community Server 5.7.19 Installation Guide (Detailed)

MySQL official website zip file download link htt...

Paragraph layout and line breaks in HTML web pages

The appearance of a web page depends largely on i...

Example code for implementing background blur effect with CSS

Is it the effect below? If so, please continue re...

mysql8.0.11 winx64 manual installation and configuration tutorial

First of all, let me talk to you about my daily l...

A Brief Analysis of MySQL Connections and Collections

Join query A join query refers to a matching quer...