1. The Portal component is updated

1. The API returns $$type as portal, which is at the same level as reactElement

One object structure returned directly by reactdom.createPortal has children

 return {
    // This tag allow us to uniquely identify this as a React Portal
    $$typeof: REACT_PORTAL_TYPE,
    key: key == null ? null : '' + key,
    children,
    containerInfo,
    implementation,
  };
Copy the code

So at the beginning of the creation of the Fiber tree this node is just a fiber, but tag=5 children is the children that’s passed in and it’s just the same as before except that in the commit phase it’s going to mount this node somewhere else

{this.state.show ? (
          <p class='ta'>{ReactDOM.createPortal(<span>123</span>, portalElm)}</p>
        ) : null}
Copy the code

The props for the p tag are as follows

Prove that the reactdom. createPortal function returns a common object called concilechildren that is a fiber

 {
    // This tag allow us to uniquely identify this as a React Portal
    $$typeof: REACT_PORTAL_TYPE,
    key: key == null ? null : ' ' + key,
    children,
    containerInfo,
    implementation,
  };
Copy the code

So the next time you performunitofwork it’s going to be this fiber tag and it’s going to be 4 and it’s going to go all the way down and create the fiber tree

But the final element to move is in the COMMIT phase

2. ForwardRef update

The types of the react internal components are the following objects

return {
    $$typeof: REACT_FORWARD_REF_TYPE, / /! Give a specific ref_type
    render,/ /! Render is the function component that is passed in
  };
Copy the code

The fiber property of the parent element as a whole is still only protal is typeof and then everything else that doesn’t have type is typeof and then everything else that doesn’t have type is typeof and then everything else that doesn’t have type is typeof and then everything else is typeof: React_element is then distinguished by $$type of type

{
	pendingprops: {children: {$$typeof: react_element,
			type: {$$typeof: REACT_FORWARD_REF_TYPE,
				render
			}
		}
	}
}
Copy the code

Update the forwardRef to create fiber’s first children from the render call that returns the same children as the function component

function updateForwardRef(
  current: Fiber | null,
  workInProgress: Fiber,
  type: any,
  nextProps: any,
  renderExpirationTime: ExpirationTime,
) {
  const render = type.render;
  const ref = workInProgress.ref;/ /! Get the incoming ref passed to the forward component and automatically call react.createElement, but the ref won't merge with prop, so it goes directly to Fiber
  if (hasLegacyContextChanged()) {/ /! The context related
    // Normally we can bail out on props equality but if context has changed
    // we don't do the bailout and we have to reuse existing props instead.
  } else if (workInProgress.memoizedProps === nextProps) {
    constcurrentRef = current ! = =null ? current.ref : null;
    if (ref === currentRef) {/ /! If ref does not change, the ForwardRef update can only change the ref
      returnbailoutOnAlreadyFinishedWork( current, workInProgress, renderExpirationTime, ); }}/ /! The children of the function component need to reconcile
  let nextChildren;
  if (__DEV__) {
    ReactCurrentOwner.current = workInProgress;
    ReactCurrentFiber.setCurrentPhase('render');
    nextChildren = render(nextProps, ref);/ /! Take the ref and pass it as an argument to the function component and the function component is a normal function that doesn't have a separate fiber and returns the value directly as the children of Forwrardref
    ReactCurrentFiber.setCurrentPhase(null);
  } else {
    nextChildren = render(nextProps, ref);
  }

  reconcileChildren(
    current,
    workInProgress,
    nextChildren,
    renderExpirationTime,
  );
  return workInProgress.child;
}
Copy the code

3. Update the mode component

When we get to this mode component, There’s a mode property in the Fiber object of the mode component and for you the mode for example concurrentMODE is binary and the child component all the children fiber will continue to use the mode value of the parent component to keep track of which mode the subtree is in, The creation of a child component updates the EXPIRationTime with a special calculation

4. The Memo component is updated

api

export default function memo<Props> (type: React$ElementType, compare? : (oldProps: Props, newProps: Props) => boolean,) {
  if (__DEV__) {
    if(! isValidElementType(type)) { warningWithoutStack(false.'memo: The first argument must be a component. Instead ' +
          'received: %s',
        type === null ? 'null' : typeoftype, ); }}return {
    $$typeof: REACT_MEMO_TYPE,
    type,
    compare: compare === undefined ? null : compare,
  };
}
Copy the code

Returns the object as type

{
    $$typeof: REACT_MEMO_TYPE,
    type,/ /! This type is the type of the functionComponent we passed in
    compare: compare === undefined ? null : compare,
  };
Copy the code

Source:

function updateMemoComponent( current: Fiber | null, workInProgress: Fiber, Component: any, nextProps: any,//! Because react. CreateElement would automatically set props updateExpirationTime, renderExpirationTime: ExpirationTime,): null | Fiber { if (current === null) {//! Current === null let type = component.type; / /! First render //! Component is the object {// $$typeof: REACT_MEMO_TYPE, // type,//! // compare: compare === undefined? null : compare, // }; / /! The access type is a function of the component (call the first parameter) coming from the memo type if (isSimpleFunctionComponent (type) && Component.com pare said = = = null) {/ /! Take a look at the second parameter we passed in which is the condition not to refresh the component if //! IsSimpleFunctionComponent said is a pure function components not class components / / If this is a plain function component without default props, // and with only the default shallow comparison, we upgrade it // to a SimpleMemoComponent to allow fast path updates. workInProgress.tag = SimpleMemoComponent; workInProgress.type = type; return updateSimpleMemoComponent(//! Refresh component current, workInProgress, type,//! NextProps, updateExpirationTime, renderExpirationTime,); } / /! This is the first time to create Here directly create child function components of fiber as a memo children (not function components of the children of the fiber as a child) let child = createFiberFromTypeAndProps ( Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime, ); child.ref = workInProgress.ref; child.return = workInProgress; workInProgress.child = child; return child; } / /! CurrentChild = ((current.child: any): fiber); // This is always exactly one child if ( updateExpirationTime === NoWork || updateExpirationTime > renderExpirationTime//! {// This will be the props with resolved defaultProps, // unlike current.memoizedProps which will be the unresolved ones. const prevProps = currentChild.memoizedProps; // Default to shallow comparison let compare = Component.compare; compare = compare ! == null ? compare : shallowEqual; / /! If (compare(prevProps, nextProps) && current. Ref === workinprogress.ref) {//! Incoming! Compare returns true does not need to update the return bailoutOnAlreadyFinishedWork (/ /! Current, workInProgress, renderExpirationTime,); }} / /! Child let newChild = createWorkInProgress(currentChild,//! Function component nextProps,//! New props renderExpirationTime,); newChild.ref = workInProgress.ref; newChild.return = workInProgress; workInProgress.child = newChild; return newChild; } function updateSimpleMemoComponent( current: Fiber | null, workInProgress: Fiber, Component: any, nextProps: any, updateExpirationTime, renderExpirationTime: ExpirationTime, ): null | Fiber { if ( current ! == null && (updateExpirationTime === NoWork || updateExpirationTime > renderExpirationTime)//! {const prevProps = current. MemoizedProps; if ( shallowEqual(prevProps, nextProps) &&//! Ref === workinprogress.ref) {//! Don't update the return bailoutOnAlreadyFinishedWork (current, workInProgress renderExpirationTime,); }} / /! Think of this Component as a function Component update Component is that function children get return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime, ); }Copy the code

1. Not simple updates

The memo is created by creating the internal function component fiber as the child(pass it to the props), just adding an extra layer to determine whether to update

The memo update is to reuse fiber and change the props to the function component before recocile its children

2. Simple update updateSimpleMemoComponent namely

And then the memo child is the first component of the children of the function, the fiber, and the fiber is gone

UpdateSimpleMemoComponent this method (directly to update function components namely child components) rather than walk createWorkInProgress this method