React is one of the author’s main technology stack, hard to avoid some want to explore the internal mechanism, the author will from the component initialization and mount, task scheduling, component types and life cycle, transactions and events, such as hook direction to study analysis (based on 16.8.6 version), for the first time to source the analytical writing, if there are any inappropriate place, Friends are welcome to point out and discuss, learn and progress together.
Let’s first look at the React component initialization
What are components
Start by writing the simplest component
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>This is Component App</div>); }}console.log(<App />)
export default App;
Copy the code
This code implements the
:
Because the
How does the React component implement HTML tags that are actually objects?
We explored the source of the code’s component declaration, so we opened the react. Development.js in the React umD specification and saw the following code:
When we import React, {Component} from ‘React’, we import the React object provided in the source code. When extends Component, you inherit the Component class. Component is a reference to a React.Component. That means Component = = = React.Com ponent, can be written in the actual project.
Follow the Component clue in this file to find its trail:
The above code is all too familiar. At the same time, we also found that setState is a method defined with two parameters on the prototype, the principle of which will be explained in a subsequent chapter.
This code shows that the Component App we declared at the beginning inherits the Component class, with its prototype setState and other methods. In this way, the component App has already had the most basic prototype.
Initialization of components
Once we declare our App, we can either customize the methods inside it, or we can use the lifecycle methods, just like we did when we wrote the “class”. The only difference is that the Component class must have the Render method output a structure like
and mount it to the real DOM in order to trigger the Component’s life cycle and become part of the DOM tree. First let’s look at how the ES6 “class” initializes a React component.
Put the original code into Babel
The _Component is the Component object and the _inherit method is a function implementation of the extends keyword. The key is we found the render method is actually invoked the _react. Default. The createElement method method. Then we continue our search for createElement in our source file:
Search for ReactElement:
Here we see that each component object is an object created through the ReactElement method. In other words, a ReactElment is an object that internally records the characteristics of a component. In ReactElement:
? typeof
: Mark each ReactElement with a symboltype
: Determines how to create a nodekey
: DOM structure identifier to improve update performanceref
: real DOMprops
: substructure-related information (add children field/not empty) and component properties (style, etc.)- _owner: _owner = = = ReactCurrentOwner. Current value to create the current component object, the default value is null
In general, ReactElement is a container used to hold information, which is very important for building the tree structure of the application later.
Mount components
We all know that you can mount custom components/native DOM/ strings via reactdom.render (Component, mountNode).
React-dom (umD) {react-dom.development.js (umD);}
Root is null since it is the first render update, just look! Root, it calls the legacyCreateRootFromDOMContainer, we then look down:
Now forceHydrate is false, so see shouldHydrateDueToLegacyHeuristic (container) return of is what?
The first node of a Container does not have the data-Reactroot attribute. Therefore, a while loop is executed to delete child nodes of the Container. After the deletion is complete, a New instance of Reactroot is created. So the flag for server rendering is to fetch the first node (or document node) in the Container and see if that node has ROOT_ATTRIBUTE_NAME.
Following ReactRoot’s lead, create FiberRoot via createContainer, a FiberRoot object that is very, very important during late schedule updates.
We found that after calling the updateContainer method, internal start computing time requestCurrentTime (), computeExpirationForFiber () the moment regardless of the details.
EnqueueUpdate () and scheduleWork() are the most important and complex tasks. UpdateContainer () returns a expirationTime.
To put an end to this first, then we return to legacyRenderSubtreeIntoContainer function to look down Eventually returned to the getPublicRootInstance:
Container. Current has no child nodes when React is initialized, so null is returned.
Finally, we add to the previous mind map:
It’s a little long, so I’ll leave it there for now. How the component is mounted to the real DOM and its task scheduling will be explained in the next article.
Reference article: juejin.cn/post/684490…