ReactDom.render源码解析

react是如何生成页面的呢?从react框架的入口可以看到app.js的内容是

ReactDOM.render(

)

从源码的reactDOM.js中找到render:

const ReactDOM: Object = {
.....

render(
  //元素  
    element: React$Element,
  //根节点
    container: DOMContainer,
  //回调函数
    callback: ?Function,
  ) {
    invariant(
      isValidContainer(container),
      'Target container is not a DOM element.',
    );
    if (__DEV__) {
    //校验container参数
      warningWithoutStack(
        !container._reactHasBeenPassedToCreateRootDEV,
        'You are calling ReactDOM.render() on a container that was previously ' +
          'passed to ReactDOM.%s(). This is not supported. ' +
          'Did you mean to call root.render(element)?',
        enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot',
      );
    }
    //调用legacyRenderSubtreeIntoContainer方法并返回
    return legacyRenderSubtreeIntoContainer(
      null,
      element,
      container,
      false,
      callback,
    );
  },
.....
}

render最终返回的legacyRenderSubtreeIntoContainer函数


function legacyRenderSubtreeIntoContainer(
  parentComponent: ?React$Component, //父组件,没有就传null
  children: ReactNodeList, //子元素
  container: DOMContainer,//根节点
  forceHydrate: boolean,//协调更新 false
  callback: ?Function,  //回调函数
) {
  if (__DEV__) {
    topLevelUpdateWarnings(container);
    warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
  }

  // TODO: Without `any` type, Flow says "Property cannot be accessed on any
  // member of intersection type." Whyyyyyy.
  let root: _ReactSyncRoot = (container._reactRootContainer: any);
  let fiberRoot;
  //第一次渲染的时候没有已存在的root
  if (!root) {
    // Initial mount
    // 创建 root
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
      container,
      forceHydrate,
    );
    fiberRoot = root._internalRoot;
    //执行回调
    if (typeof callback === 'function') {
      const originalCallback = callback;
      callback = function() {
        const instance = getPublicRootInstance(fiberRoot);
        originalCallback.call(instance);
      };
    }
    // Initial mount should not be batched.
    unbatchedUpdates(() => {
      updateContainer(children, fiberRoot, parentComponent, callback);
    });
  } else {
    fiberRoot = root._internalRoot;
    if (typeof callback === 'function') {
      const originalCallback = callback;
      callback = function() {
        const instance = getPublicRootInstance(fiberRoot);
        originalCallback.call(instance);
      };
    }
    // Update
    updateContainer(children, fiberRoot, parentComponent, callback);
  }
  return getPublicRootInstance(fiberRoot);
}

你可能感兴趣的:(ReactDom.render源码解析)