React Fiber结构的创建步骤

 更新时间:2021年04月15日 10:04:40   作者:光光同学22167  
这篇文章主要介绍了React Fiber结构的创建步骤,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下

React Fiber的创建

当前React版本基于V17.0.2版本,本篇主要介绍fiber结构的创建。

一、开始之前

个人理解,如有不对,请指出。

首先需要配置好React的debugger开发环境,入口在这里:github

执行npm run i,安装依赖,npm start运行环境。

二、从React.render开始

通过在项目入口处调用React.render,打上Debug,查看React调用栈。

const root = document.getElementById('root');
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  root
);

在React调用render之后,在传入基础的配置后,调用legacyRenderSubtreeIntoContainer。

export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function,
) {
  // 删除一些环境代码
  // ...
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

在React调用render之后,在传入基础的配置后,调用legacyRenderSubtreeIntoContainer。

export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function,
) {
  // 删除一些环境代码
  // ...
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

legacyRenderSubtreeIntoContainer一共做了两件事情,一个是生成了fiberRoot,一个是调用updateContainer。

进入legacyCreateRootFromDOMContainer函数,查看如何生成fiberRoot。 在函数内部,调用了createLegacyRoot,在这里区分了下,是否使用hydrate,如下:

  return createLegacyRoot(
    container,
    shouldHydrate
      ? {
        hydrate: true,
      }
      : undefined,
  );

对于createLegacyRoot来说,是用来实例化ReactDOMLegacyRoot函数的,通过后续调用,终于进入到root的生成,调用createRootImpl函数,实例化root。

进入createFiberRoot函数,初始化FiberRootNode。

function FiberRootNode(containerInfo, tag, hydrate) {
  this.tag = tag; // 类型
  this.containerInfo = containerInfo; // container
  this.pendingChildren = null; 
  this.current = null;
  this.pingCache = null;
  this.finishedWork = null;
  this.timeoutHandle = noTimeout;
  this.context = null;
  this.pendingContext = null;
  this.hydrate = hydrate;
  this.callbackNode = null;
  this.callbackPriority = NoLanePriority;
  this.eventTimes = createLaneMap(NoLanes);
  this.expirationTimes = createLaneMap(NoTimestamp);

  this.pendingLanes = NoLanes;
  this.suspendedLanes = NoLanes;
  this.pingedLanes = NoLanes;
  this.mutableReadLanes = NoLanes;
  this.finishedLanes = NoLanes;

  this.entangledLanes = NoLanes;
  this.entanglements = createLaneMap(NoLanes);

  // ....


}

这里的tag,有以下几种类型。

export type RootTag = 0 | 1;

上述的结构是fiberRootNode节点。

rootTag 等于0 时,代表legacy渲染模式,等于1时,代表Concurrent mode渲染,也就是说,传统我们使用React.render进行渲染,当调用React.createRoot时,进入Concurrent mode渲染模式,即并行渲染。

现在我们一起看看fiber的结构。

  const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride);
  root.current = uninitializedFiber;
  uninitializedFiber.stateNode = root;

uninitializedFiber为创建的FiberNode的创建的实例。

const createFiber = function(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
): Fiber {
  // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
  return new FiberNode(tag, pendingProps, key, mode);
};

通过基础的创建,生成FiberNode结构,如下

function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // Instance
  this.tag = tag;//组件类型
  this.key = key;//key属性
  this.elementType = null;//元素类型,类函数,显示类,div显示div
  this.type = null;//func或者class
  this.stateNode = null;//dom节点

  // Fiber
  this.return = null;//指向父节点
  this.child = null;//指向子节点
  this.sibling = null;//兄弟节点
  this.index = 0;//

  this.ref = null;

  this.pendingProps = pendingProps;//等待中的属性pendingProps
  this.memoizedProps = null; //记忆属性,一般存放props
  this.updateQueue = null;//更新队列
  this.memoizedState = null;// 一般存放state
  this.dependencies = null;

  this.mode = mode;

  // Effects相关
  this.flags = NoFlags;
  this.subtreeFlags = NoFlags;
  this.deletions = null;

  this.lanes = NoLanes;
  this.childLanes = NoLanes;

  this.alternate = null;//指向workInProgress
}

 FiberNode基本显示如上,elementType和type的基础类型为function、class。

通过对比fiberRootNode结构,和下面的代码,生成最终的FiberNode 结构。

render() {
    const { name, count } = this.state;
    return (
      <div className="App">
          <Button name={name} />
        {
          count
        }
      </div>
    );
  }
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  root
);

通过最后执行,生成fiberRoot链表结构。

最后,调用unbatchedUpdates,进行渲染。

进入updateContainer函数。

unbatchedUpdates(() => {
  // 更新container
  updateContainer(children, fiberRoot, parentComponent, callback);
});

三、结束

以上就是React Fiber结构的创建步骤的详细内容,更多关于React Fiber结构的创建的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:

相关文章

  • 详解如何在项目中使用jest测试react native组件

    详解如何在项目中使用jest测试react native组件

    本篇文章主要介绍了详解如何在项目中使用jest测试react native组件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • 深入浅析React refs的简介

    深入浅析React refs的简介

    React中的Refs提供了一种方式,允许我们访问DOM节点或在render方法中创建的React元素,本文给大家介绍react refs的相关知识,感兴趣的朋友一起看看吧
    2021-07-07
  • 详解React 16 中的异常处理

    详解React 16 中的异常处理

    这篇文章主要介绍了详解React 16 中的异常处理的相关资料,React 16.x 版本中,引入了所谓 Error Boundary 的概念,从而保证了发生在 UI 层的错误不会连锁导致整个应用程序崩溃;未被任何异常边界捕获的异常可能会导致整个 React 组件树被卸载,需要的朋友可以参考下
    2017-07-07
  • 浅谈React中组件逻辑复用的那些事儿

    浅谈React中组件逻辑复用的那些事儿

    这篇文章主要介绍了浅谈React中组件逻辑复用的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • 深入理解React中es6创建组件this的方法

    深入理解React中es6创建组件this的方法

    this的本质可以这样说,this跟作用域无关的,只跟执行上下文有关。接下来通过本文给大家介绍React中es6创建组件this的方法,非常不错,感兴趣的朋友一起看看吧
    2016-08-08
  • React Native预设占位placeholder的使用

    React Native预设占位placeholder的使用

    本篇文章主要介绍了React Native预设占位placeholder的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • react native 仿微信聊天室实例代码

    react native 仿微信聊天室实例代码

    这篇文章主要介绍了react native 仿微信聊天室实例代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 利用React-router+Webpack快速构建react程序

    利用React-router+Webpack快速构建react程序

    目前 React、Webpack 等技术如火如荼,你是不是还在愁苦如何把这些杂乱的知识怎么学习一下,开启一段新的前端开发之路呢?那么这篇将给大家运用示例代码详细的介绍使用React-router和Webpack如何快速构建一个react程序,感兴趣的朋友们下面来一起看看吧。
    2016-10-10
  • react-router4 配合webpack require.ensure 实现异步加载的示例

    react-router4 配合webpack require.ensure 实现异步加载的示例

    本篇文章主要介绍了react-router4 配合webpack require.ensure 实现异步加载的示例,非常具有实用价值,需要的朋友可以参考下
    2018-01-01
  • 浅谈箭头函数写法在ReactJs中的使用

    浅谈箭头函数写法在ReactJs中的使用

    这篇文章主要介绍了浅谈箭头函数写法在ReactJs中的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08

最新评论