Thank yck: analyze the source code of React , this article is based on reading his article, disassembling and processing his article, adding my own understanding and examples for everyone to understand. Think yck It's really great. The React version is 16.8.6. For reading the source code, you can go to Source code analysis of yck react
Permanent links to this article: react parsing: update in render (4)
Previous chapter Say that there is no root data node, that is, throughcreateFiberRoot function to create a FiberRoot , the FiberRoot object is the starting point of the whole React application, and also records all kinds of information during the update process of the whole React application.
What we'll talk about next is what happens when root is created.
legacyRenderSubtreeIntoContainer function
The following links up the previous part. I don't know how to view itPrevious chapter.
yck: ReactDOM source code 554 lines legacyRenderSubtreeIntoContainer
function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Component<any, any>, children: ReactNodeList, container: DOMContainer, forceHydrate: boolean, callback: ?Function, ) { // When initializing, the container must not have the "react rootcontainer" property let root: Root = (container._reactRootContainer: any); if (!root) { // Omit the create root section unbatchedUpdates(() => { if (parentComponent != null) { root.legacy_renderSubtreeIntoContainer( parentComponent, children, callback, ); } else { root.render(children, callback); } }); } }
When root is just created, parentComponent is generally null;
The unbatchedUpdates function is used here to tell React not to batch update, that is, not to merge multiple setstates into one;
(we'll talk about setState later)
In this case, the root.render function is actually called. Root is the ReactRoot instance object, that is, the root.render function = = ReactRoot.prototype.render function is called.
ReactRoot.prototype.render function
yck: ReactRoot source code line 377 ReactRoot.prototype.render
ReactRoot.prototype.render = function( children: ReactNodeList, callback: ?() => mixed, ): Work { // This is FiberRoot. const root = this._internalRoot; const work = new ReactWork(); callback = callback === undefined ? null : callback; // If there is a callback, push it into the array in work if (callback !== null) { work.then(callback); } // Work. Oncommit is used to execute all callback functions. updateContainer(children, root, null, work._onCommit); return work; };
The parameter children in the function is the ReactElement node object, and callback is the callback function. The main function of the ReactWork instance object is to maintain a callback array, which can be viewed. yck: ReactWork source code line 327 , if there is a callback in the incoming parameter, it will be attached to the ReactWork instance object;
Let's see what the updateContainer function does.
updateContainer function
yck: ReactFiberReconciler source code 284 line updateContainer
export function updateContainer( element: ReactNodeList, container: OpaqueRoot, parentComponent: ?React$Component<any, any>, callback: ?Function, ): ExpirationTime { const current = container.current; // computing time const currentTime = requestCurrentTime(); // expirationTime represents priority, the higher the number, the higher the priority // sync has the largest number, so it has the highest priority const expirationTime = computeExpirationForFiber(currentTime, current); return updateContainerAtExpirationTime( element, container, parentComponent, expirationTime, callback, ); }
container.current is to take out the RootFiber object from the FiberRoot, and currentTime is the current time when the React application is initialized. **expirationTime literally means expiration time. I will spend a chapter to introduce these two times, which are also the focus of React application task scheduling.
scheduleRootUpdate function
The updateContainerAtExpirationTime function actually calls the scheduleRootUpdate function. Let's talk about the role of the scheduleRootUpdate function.
Yck: realfiberreconciler source code line 114 scheduleRootUpdate
function scheduleRootUpdate( current: Fiber, element: ReactNodeList, expirationTime: ExpirationTime, callback: ?Function, ) { // Create an update, which is an object with several internal properties const update = createUpdate(expirationTime); update.payload = {element}; // Callback function in render callback = callback === undefined ? null : callback; if (callback !== null) { update.callback = callback; } flushPassiveEffects(); // To queue an update is to create or get a queue (linked list structure) and then add a node to the linked list. enqueueUpdate(current, update); scheduleWork(current, expirationTime); return expirationTime; }
Here are the properties in the update object:
// update object properties export type Update<State> = { // Expiration time of update expirationTime: ExpirationTime, // export const UpdateState = 0; // export const ReplaceState = 1; // export const ForceUpdate = 2; // export const CaptureUpdate = 3; // Specify the type of update with the above values tag: 0 | 1 | 2 | 3, // Update content, such as the first parameter received by 'setState' payload: any, // The corresponding callbacks, 'setState', and 'render' all have callback: (() => mixed) | null, // Point to next update next: Update<State> | null, // Point to next ` side effect` nextEffect: Update<State> | null, };
The udate object will be inserted into the task queue maintained by the React application, regardless of whether you are updating the React application caused by setState or React dom.render. The core function of this function is to create or get a queue, and then insert the update object into the queue to update. The scheduleWork function is the job scheduling thing.
More:
React resolution: React.createElement(1)
React analysis: React.Children(2)
react parsing: render's FiberRoot(3)
Reference resources:
yck: dissecting the source code of React
Jokcy's "React source code analysis": react.jokcy.me/
ps: by the way, my personal public number: Yopai. You can pay attention to it if you are interested, update it irregularly every week, and share it to increase the happiness of the world.