>  기사  >  웹 프론트엔드  >  ReactDom.render의 상세 분석

ReactDom.render의 상세 분석

不言
不言앞으로
2019-04-04 11:09:534006검색

이 기사는 ReactDom.render에 대한 자세한 분석을 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

단계

1. ReactRoot 생성

2. FiberRoot 및 FiberRoot 생성

3. 업데이트 생성

render 메소드는 ReactElement 및 DOM 패키지 노드를 포함한 세 가지 매개변수를 전달할 수 있습니다. 렌더링 후에 실행되는 콜백 메서드입니다. 그런 다음 invariant를 확인하여 컨테이너가 유효한 Dom 노드인지 확인하세요.

마지막으로 legacyRenderSubtreeIntoContainer 메소드가 실행된 후 결과를 반환합니다. 이 메소드의 매개변수를 살펴보겠습니다.

render(
    element: React$Element<any>,
    container: DOMContainer,
    callback: ?Function,
  ) {
    invariant(
      isValidContainer(container),
      'Target container is not a DOM element.',
    );
    return legacyRenderSubtreeIntoContainer(
      null,
      element,
      container,
      false,
      callback,
    );
  },
여기에는 5개의 매개변수가 전달됩니다. 첫 번째는 parentComponent가 존재하지 않는다는 것입니다. 그리고 null이 전달됩니다. 두 번째는 들어오는 컨테이너의 하위 요소이고, 세 번째는 ReactRoot를 생성하는 래핑 요소이고, 네 번째는 업데이트를 조정하는 옵션이고, 다섯 번째는 렌더링 후 콜백 메서드입니다.
function legacyRenderSubtreeIntoContainer(
  parentComponent: ?React$Component<any, any>,
  children: ReactNodeList,
  container: DOMContainer,
  forceHydrate: boolean,
  callback: ?Function,
)
먼저 ReactRoot가 존재하는지 확인한 다음, forceHydrate가 ReactRoot를 생성한 후 legacyCreateRootFromDOMContainer 함수를 실행합니다. render 메소드에서 forceHydrate에 전달된 false와 Hydrate 메소드에 전달된 true는 주로 서버 측 렌더링과 클라이언트 측 렌더링을 구별하기 위한 것입니다. true일 경우 원본 노드는 재사용되지 않으며 서버 측 렌더링에 적합합니다. false인 경우 container.removeChild(rootSibling)를 실행하고 모든 하위 노드를 삭제합니다.
그런 다음 new ReactRoot(container, isConcurrent, shouldHydrate)를 통해 루트 생성으로 돌아갑니다.
let root: Root = (container._reactRootContainer: any);
  if (!root) {
    // Initial mount
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
      container,
      forceHydrate,
    );
invariant验证container是否是有效的Dom节点。
最后返回legacyRenderSubtreeIntoContainer方法执行后的结果,再来看看这个方法的参数
function ReactRoot(
  container: DOMContainer,
  isConcurrent: boolean,
  hydrate: boolean,
) {
  const root = createContainer(container, isConcurrent, hydrate);
  this._internalRoot = root;
}
这里传入五个参数,第一个是parentComponent不存在传入null,第二个是传入container的子元素,第三个是创建ReactRoot的包裹元素,第四个是协调更新的选项,第五个是渲染后的回调方法。
export function createContainer(
  containerInfo: Container,
  isConcurrent: boolean,
  hydrate: boolean,
): OpaqueRoot {
  return createFiberRoot(containerInfo, isConcurrent, hydrate);
}
先检验ReactRoot是否存在不存在则执行传入container,
forceHydrate后的legacyCreateRootFromDOMContainer函数创建一个ReactRoot。forceHydrate在render方法中传入的false,在Hydrate方法中传入的true,主要是为了区分服务端渲染和客户端渲染,true时未复用原来的节点适合服务端渲染,
如果是false则执行container.removeChild(rootSibling)删除所有的子节点。
然后返回通过 new ReactRoot(container, isConcurrent, shouldHydrate)
unbatchedUpdates(() => {
      if (parentComponent != null) {
        root.legacy_renderSubtreeIntoContainer(
          parentComponent,
          children,
          callback,
        );
      } else {
        root.render(children, callback);
      }
    });

在这个方法中调用createContainer创建root,这个方法从react-reconciler/inline.dom文件中引入:

rrreee

在这个方法中又调用了createFiberRoot方法创建FiberRoot
在创建玩root后执行unbatchedUpdates更新,传入root。render方法更新:

rrreee

执行updateContainer(children, root, null, work._onCommit);方法,这个方法最终调用enqueueUpdatescheduleWork이 메서드에서 createContainer를 호출하세요. 이 메서드는 에서 시작됩니다. 반응 -reconciler/inline.dom 파일에 도입됨:

rrreee

이 메서드에서는 createFiberRoot 메서드가 호출되어 FiberRoot를 생성합니다.루트를 생성한 후 unbatchedUpdates 업데이트, 루트에 전달합니다. 렌더링 메서드 업데이트: rrreee

updateContainer(children, root, null, work._onCommit); 메서드를 실행하여 최종적으로 enqueueUpdatescheduleWork를 호출합니다. >, 그리고 스케줄링 알고리즘과 우선순위 판단을 수행하는expirationTime을 반환합니다

[관련 추천: 🎜react 비디오 튜토리얼🎜]🎜🎜🎜

위 내용은 ReactDom.render의 상세 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제