React16源码: React中的completeWork对HostText处理含更新的源码实现

HostText


1 )概述

  • completeWork 中 对 HostText的处理
  • 在第一次挂载和后续更新的不同条件下进行操作
    • 第一次挂载主要是创建实例
    • 后续更新其实也是重新创建实例

2 )源码

定位到 packages/react-reconciler/src/ReactFiberCompleteWork.js#L663

case HostText 这里

case HostText: {
  let newText = newProps;
  // 符合这个条件,说明它不是第一次渲染,就是更新的状态
  // 调用 updateHostText 进行更新
  if (current && workInProgress.stateNode != null) {
    const oldText = current.memoizedProps;
    // If we have an alternate, that means this is an update and we need
    // to schedule a side-effect to do the updates.
    updateHostText(current, workInProgress, oldText, newText);
  } else {
    // 对于第一次渲染
    if (typeof newText !== 'string') {
      invariant(
        workInProgress.stateNode !== null,
        'We must have new props for new mounts. This error is likely ' +
          'caused by a bug in React. Please file an issue.',
      );
      // This can happen when we abort work.
    }
    // 跳过 context 处理
    const rootContainerInstance = getRootHostContainer();
    const currentHostContext = getHostContext();
    // 跳过 hydrate 处理
    let wasHydrated = popHydrationState(workInProgress);
    if (wasHydrated) {
      if (prepareToHydrateHostTextInstance(workInProgress)) {
        markUpdate(workInProgress);
      }
    } else {
      // 创建 文本 实例
      workInProgress.stateNode = createTextInstance(
        newText,
        rootContainerInstance,
        currentHostContext,
        workInProgress,
      );
    }
  }
  break;
}
  • 进入 updateHostText

    updateHostText = function(
      current: Fiber,
      workInProgress: Fiber,
      oldText: string,
      newText: string,
    ) {
      // 这个非常简单,通过前后 text 是否有区别
      // 如果不同,则创建新的 text实例
      if (oldText !== newText) {
        // If the text content differs, we'll create a new text instance for it.
        // 先跳过 context 的处理
        const rootContainerInstance = getRootHostContainer();
        const currentHostContext = getHostContext();
        workInProgress.stateNode = createTextInstance(
          newText,
          rootContainerInstance,
          currentHostContext,
          workInProgress,
        );
        // We'll have to mark it as having an effect, even though we won't use the effect for anything.
        // This lets the parents know that at least one of their children has changed.
        markUpdate(workInProgress);
      }
    };
    
    • 进入 createTextInstance
      // packages/react-dom/src/client/ReactDOMHostConfig.js#L272
      export function createTextInstance(
        text: string,
        rootContainerInstance: Container,
        hostContext: HostContext,
        internalInstanceHandle: Object,
      ): TextInstance {
        if (__DEV__) {
          const hostContextDev = ((hostContext: any): HostContextDev);
          validateDOMNesting(null, text, hostContextDev.ancestorInfo);
        }
        const textNode: TextInstance = createTextNode(text, rootContainerInstance);
        // 这个方法之前阅过
        precacheFiberNode(internalInstanceHandle, textNode);
        return textNode;
      }
      
      • 进入 createTextNode
        export function createTextNode(
          text: string,
          rootContainerElement: Element | Document,
        ): Text {
          // 最终 getOwnerDocumentFromRootContainer 这里返回一个dom对象,调用dom的 createTextNode 这个方法
          return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(
            text,
          );
        }
        
        • 进入 getOwnerDocumentFromRootContainer
        function getOwnerDocumentFromRootContainer(
          rootContainerElement: Element | Document,
        ): Document {
          // rootContainerElement.ownerDocument 这里是 window.document 对象
          // 这么做是为了兼容多平台api的使用
          return rootContainerElement.nodeType === DOCUMENT_NODE
            ? (rootContainerElement: any)
            : rootContainerElement.ownerDocument;
        }
        
  • HostText 相比于 HostComponents 来说,它没有多种选择

  • 没有各种各样的属性,整体来说非常的简单

  • 一些特别说明的,写在了上述代码注释中

你可能感兴趣的:(React,React,Native,react.js,前端,前端框架)