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

Problems encountered by MySQL nested transactions

MySQL supports nested transactions, but not many ...

How to disable web page styles using Firefox's web developer

Prerequisite: The web developer plugin has been in...

4 solutions to CSS browser compatibility issues

Front-end is a tough job, not only because techno...

How to parse the attribute interface of adding file system in Linux or Android

The first one: 1. Add key header files: #include ...

Detailed explanation of MySQL master-slave database construction method

This article describes how to build a MySQL maste...

Tutorial on installing MySQL 8.0.11 under Linux

1. Go to the official website to download the ins...

JavaScript canvas Tetris game

Tetris is a very classic little game, and I also ...

Error mysql Table 'performance_schema...Solution

The test environment is set up with a mariadb 5.7...

How to create scheduled tasks using crond tool in Linux

Preface Crond is a scheduled execution tool under...

11 Reasons Why Bootstrap Is So Popular

Preface Bootstrap, the most popular front-end dev...

MySQL sorting using index scan

Table of contents Install sakila Index Scan Sort ...

How to reduce the memory and CPU usage of web pages

<br />Some web pages may not look large but ...

How to build your own Angular component library with DevUI

Table of contents Preface Creating a component li...

How to configure Linux to use LDAP user authentication

I am using LDAP user management implemented in Ce...