1.react package


React Core Functionality and API This package provides core functionality for creating React components, state management, lifecycle methods, and more. This package is a must for any project using React.


  1. React Element Creation: react provides the React.createElement() method, which allows developers to define UI structures. This is mostly done indirectly through the JSX syntax, as JSX is compiled into React.createElement() calls.

  2. Component and Class Definitions: Provides the basic mechanism for creating components, including the React.Component and React.PureComponent base classes. These classes provide the ability to define the lifecycle methods, state ( state ), and properties ( props ) of a component.

  3. Hooks: As of React 16.8, react introduces the Hooks API, including useState , useEffect , useContext , useReducer , etc., which enables the use of state management and lifecycle features in function components.

  4. Context: Provides a Context API, i.e. React.createContext , Context.Provider , Context.Consumer , etc., which can pass data directly across component hierarchies without having to pass it layer by layer through props.

  5. Fragment: React.fragment ( <>...</> ) is a way to make a component return multiple elements.

  6. Refs: APIs such as React.createRef , React.forwardRef are provided to manage direct references to DOM nodes or component instances.

  7. Error Boundary: The componentDidCatch lifecycle method in the React.Component class allows a component to intercept JS errors in its child component tree and log them.

  8. Tool Functions: The react package also contains functions such as React.Children and other helper functions for working with children props and other different kinds of tools.

2.react-dom


react-dom package is a package in the React ecosystem that is specialized for the web browser environment and provides the methods and APIs needed to interact with the DOM (Document Object Model) in the browser.


  1. Rendering: ReactDOM.render() is one of the most important methods of the react-dom package, rendering React elements into the specified DOM container. React version 18 introduced the createRoot() function for the same purpose, but in a more advanced way.

  2. Interacting with the browser: In addition to rendering elements, react-dom also handles binding and unbinding of event handlers and other tasks that require direct interaction with the browser’s DOM API.

  3. Lifecycle Hook: react-dom is responsible for calling the component’s lifecycle methods, such as mounting ( componentDidMount ), updating ( componentDidUpdate ), and unloading ( componentWillUnmount ) of the component.

  4. Portals: react-dom provides an API for creating portals. Portals provide a way to render child nodes to DOM nodes that exist outside of the parent component.

  5. Server-Side Rendering (SSR) : react-dom/server provides APIs for server-side rendering. These include renderToString() and renderToStaticMarkup() , which convert React elements to HTML strings, respectively, and can be used to generate the initial rendering of a web page.

  6. Testing Tools: react-dom provides react-dom/test-utils , a set of tools to assist in testing component behavior.

  7. Find DOM node: react-dom also provides the ReactDOM.findDOMNode() method, which can get the DOM node of the component, but it is not recommended for performance and code clarity reasons.

  8. Hydration: When server-side rendering (SSR) is used to generate HTML for a React component and it is loaded on the client, react-dom can “hydrate” that HTML, which has the effect of reconnecting event handlers, etc., without re-rendering the DOM.


In the React architecture, the react library is responsible for defining how components are created and managing state, while the react-dom library is React’s rendering engine and handles how these components are actually displayed and updated in the browser. This separation allows the same React components to work in different environments (e.g. Web, Native, VR, etc.) with different rendering engines (e.g. react-dom , react-native ).

3.react-reconciler


It provides the ability to define custom renderers and encapsulates React’s reconciliation algorithm, which is used to calculate updates. With react-reconciler , developers can create new renderers to render React components to different platforms and rendering environments, such as WebGL or a command line interface (CLI).


  1. Reconciliation Algorithm: react-reconciler implements React’s Fiber Reconciliation Algorithm, an efficient algorithm for coordinating and rendering React element trees. It allows React to pause, interrupt, and reuse work during rendering to accommodate other work in the main thread.

  2. Platform independence: Abstracting the reconciliation process from platform-specific details means that the same set of React code can be used for rendering on different platforms, and each platform only needs its own renderer.

  3. Custom Rendering: react-reconciler allows developers to create new rendering backends for a variety of output targets. The renderer is responsible for maintaining the host environment’s tree of elements and responding to create, update, or delete operations coming from React.

  4. Core API: react-reconciler package provides a Reconciler(config) function. Developers can provide a configuration object ( config ) that contains various method implementations for the host environment (e.g., browser DOM, React Native, etc.). These methods include creating, deleting, and updating nodes in the host environment, as well as inserting nodes.

  5. Custom Component Lifecycle: In addition, react-reconciler allows developers to implement custom renderer lifecycle methods, such as updating or cleaning up resources at specific points in time.

  6. Experimental feature support: Renderers built with react-reconciler have access to the latest features and improvements being developed by the React core team, such as providing support for concurrency mode.

 4. scheduler [was not available before 16]


It focuses on optimizing performance, especially related to task scheduling.The React team introduced this package to enable advanced features like Concurrent Mode, which optimizes rendering performance by orchestrating tasks with different priorities, especially in the case of large updates or when performing costly computations on the main thread.


  1. Task Scheduling: The scheduler package allows React to schedule tasks based on their priority. This means that React can decide when to execute a task and how to insert more urgent work into important renders and updates.

  2. Priority settings: This provides the ability to set the priority of different tasks so that React can prioritize high-priority tasks, such as user interactions, while deferring less urgent tasks, such as data prefetching, to a later time.

  3. Interrupting and Resuming Work: While executing long tasks, scheduler can interrupt them to ensure that the main thread is not blocked, thus keeping the application responsive. Later, once the main thread becomes free, scheduler can resume these interrupted tasks.

  4. Coordinate Multiple Tasks: It manages and coordinates the execution of multiple tasks, ensuring that tasks are executed in the correct order and priority.

  5. Avoiding main thread blocking: The scheduler package supports the browser’s requestIdleCallback() API and in this way allows tasks to be executed when the main thread is idle, which reduces blocking of the main thread and thus improves application performance.

  6. Advanced Scheduling: With experimental concurrency features, developers can utilize the scheduler package for more advanced scheduling in large applications with complex state logic and data access requirements.

  Two loops in react

 1. Task Scheduling Loop


  • The logic of the main macro to schedule is each task ( task ), and do not care about the specific task is what to do, the specific task is actually the execution of the callback function. react-reconciler After receiving (add, delete, update), and will not immediately construct the fiber tree, but go to the scheduler scheduling center to register task , task into the task queue to wait for the right time to call the callbacks in the execution of task

 2. fiber construction loop


fiber It takes  as the data structure, performs depth-first traversal from top to bottom, constructs the fiber tree, and passes commitRoot(FiberRootNode) into react-dom for dom rendering.

  III. Relationship between the two cycles


From the above figure we can see that a task mainly consists of ( fiber tree construction, DOM rendering, scheduling detection), react-reconciler registered task at a certain time for the call, the call will go to the realization of the task, which include

  •   fiber tree tectonic (geology)
  •   DOM add washes of ink or color to a drawing (Chinese painting)

  • Scheduling Detection And the fiber construction loop is one of the task implementation aspects, where tasks all reconstruct a fiber tree.

  Four, several objects of react


The following examples are all drawn with the app.js file in the source directory of the previous build!!!!

JSX


In the last two posts we’ve explored the principle of jsx , where jsx is eventually converted by babel into createElement which then creates the ReactElement

ReactElement

 1. Basic introduction


  • ReactElement is the most basic unit of the React application. It is a lightweight description of a part of the UI and is actually a regular js object that can represent a DOM node or other component part. The element ( Element ) object contains the component type (e.g. div、span or other custom component), attributes, and child elements. Elements are immutable; once created, their children or attributes cannot be changed. When you update the UI, React creates a new tree of elements to represent the new UI state.

  • react Will go and build the fiber tree based on the ReactElement

 2. Data structure

{
  $$typeof: Symbol.for('react.element'),
  type: 'div',
  key: null,
  ref: null,
  props: {
    className: 'sidebar',
    children: 'Content here' 
  },
  _owner: null,  
  _store: {}, 
  _self: null,  
  _source: null, 
}

fiber

 Basic Introduction


Fiber is a new coordination algorithm (one of the core algorithms of React) introduced in the React 16 version. It was introduced primarily to optimize the rendering flow of React so that it can perform more efficient update and task scheduling. The introduction of the Fiber architecture addresses some of the limitations of the traditional React virtual DOM algorithm (recursive comparison update strategy), such as the following:


  1. Interruptible Work: In older algorithms, once a rendering job is started, it must be completed until the entire virtual DOM tree has been compared, which can cause the main thread to be occupied for long periods of time, affecting the performance of animations, layouts, and input responses. The Fiber architecture introduces the ability to break up the rendering job into small chunks, enabling work to be interrupted and resumed, allowing the main thread to perform more urgent tasks as needed. to perform more urgent tasks as soon as they are needed.

  2. Incremental Rendering: By splitting work into a series of small tasks, React can step through the entire rendering process in this way, rather than doing it all at once. This allows important updates, such as animation frames, to be prioritized, which improves application responsiveness and performance.

  3. Better Error Handling: Fiber allows React to “catch” errors in subtrees in the component tree and up-throw them to higher error bounded ( Error Boundary ) components.

 data structure

 The data structure is roughly as follows:

export const Fiber = {
    tag: WorkTag,
    key: null | string, 
    elementType: any,
    type: any, 
    stateNode: any, 
    return: Fiber | null, 
    child: Fiber | null, 
    sibling: Fiber | null, 
    index: number, 
    ...
    ...
}

 Structures in memory

 Definitions in the source code

function FiberRootNode(
  containerInfo,
  tag,
  hydrate,
  identifierPrefix,
  onRecoverableError,
) {
  this.tag = tag;

  this.containerInfo = containerInfo;

  this.pendingChildren = null;

  this.current = null;

  this.pingCache = null;

  this.finishedWork = null;

  this.timeoutHandle = noTimeout;

  this.context = null;

  this.pendingContext = null;

  this.callbackNode = null;

  this.callbackPriority = NoLane;

  this.eventTimes = createLaneMap(NoLanes);

  this.expirationTimes = createLaneMap(NoTimestamp);

  this.pendingLanes = NoLanes;

  this.suspendedLanes = NoLanes;

  this.pingedLanes = NoLanes;

  this.expiredLanes = NoLanes;

  this.mutableReadLanes = NoLanes;

  this.finishedLanes = NoLanes;

  this.entangledLanes = NoLanes;

  this.entanglements = createLaneMap(NoLanes);

  this.identifierPrefix = identifierPrefix;

  this.onRecoverableError = onRecoverableError;
}

 V. A few questions to explore


1. Why do we need fiber data structures when we have reactElement data structures?


  • ReactElement is used to describe the UI and fiber is used to optimize React’s rendering process to perform more efficient updates and task scheduling.

  • Consider that ReactElement is still a macroscopic description of the component tree, while Fiber is an engine that works at the micro level

 2. Why not just extend ReactElement?


Extending the React Element data structure to support interruptible rendering and task scheduling (i.e., implementing the functionality of Fiber) presents several problems:


  1. Separation of Duties: The React Element is essentially a static description of the user interface, which is relatively simple. It should be kept lightweight and immutable to keep the underlying functionality of React clean and efficient. fiber, on the contrary, is responsible for handling dynamic operations such as state management, task scheduling, prioritization, and so on during rendering. These operations belong to the internal mechanisms of the React framework and are a different domain than the specific description of components (the responsibility of the React Element). Putting this complexity on the React Element would significantly increase the complexity and difficulty of maintaining this data structure.

  2. Backward compatibility: React was designed with backward compatibility in mind. Many existing applications rely on the current React Element representation and behavior. Changing the structure or behavior of a React Element in a significant way can cause extensive compatibility issues, forcing existing applications to undergo extensive refactoring.

  3. Rendering Performance: React Element serves as a declarative description of the UI, and they are created and compared in large numbers. If the dynamic behavior of rendering is incorporated into a React Element, its performance may be negatively impacted by the added complexity. The Fiber structure optimizes this process, resulting in improved performance.

  4. Clear layer of abstraction: One of React’s design philosophies is to provide a simple API and hide complex implementation details. Developers use React Element to define their components without having to worry about how React does task scheduling and state updates internally. Introducing Fiber as a separate internal mechanism allows React to maintain a clean external API while having the power needed to handle complex scenarios.

  5. Specialization: while a React Element describes what the UI looks like, a Fiber node contains not only the UI description, but also additional information needed to perform the update (e.g., current lifecycle state, pending priority updates, etc.) Fiber nodes are richer in information and are better suited to handling the update logic inside the React framework.


And fiber also needs to know what kind of UI needs to be drawn, here it just separates the UI from the drawing and task scheduling, and Fiber doesn’t create a new data structure internally that overlaps with ReactElement ‘s functionality. Instead, it uses the existing ReactElement to understand the application’s component tree and how to render UI .

By hbb

Leave a Reply

Your email address will not be published. Required fields are marked *