packages/react-reconciler/src/ReactFiber.js

Fiber

// A Fiber is work on a Component that needs to be done or was done. There can
// be more than one per component.
// Fiber 是 Component 上需要完成或已经完成工作。每个组件可以有多个 fiber。
export type Fiber = {|// These first fields are conceptually members of an Instance. This used to// be split into a separate type and intersected with the other Fiber fields,// but until Flow fixes its intersection bugs, we've merged them into a// single type.// 这些字段在概念上是实例的成员。// 这曾经被分割成一个单独的类型,并与其他 fiber 字段相交,// 但是直到 Flow 修复了它的交集错误,我们才将它们合并成一个单一的类型。// An Instance is shared between all versions of a component. We can easily// break this out into a separate object to avoid copying so much to the// alternate versions of the tree. We put this on a single object for now to// minimize the number of objects created during the initial render.// 在一个组件的所有版本之间共享的实例。// 我们可以很容易地将其拆分为一个单独的对象,// 以避免过多地复制到树的其他版本。// 现在我们将它放在一个对象上,以最小化在初始渲染期间创建的对象的数量。// 标记 fiber 类型的标签。tag: WorkTag,// 此子元素的唯一标识符。key: null | string,// The value of element.type which is used to preserve the identity during// reconciliation of this child.// element.type 的值,用于在此子元素的协调(reconciliation)过程中保存标识。elementType: any,// The resolved function/class/ associated with this fiber.//与此 fiber 相关联的已解析的 function/class/。type: any,// The local state associated with this fiber.// 与此 fiber 相关联的本地状态。stateNode: any,// Conceptual aliases// parent : Instance -> return The parent happens to be the same as the// return fiber since we've merged the fiber and instance.// 概念的别名// parent:Instance -> return// parent 恰好与 return 的 fiber 相同,因为我们已经合并了 fiber 和实例。// Remaining fields belong to Fiber// 剩余的字段属于 Fiber// The Fiber to return to after finishing processing this one.// This is effectively the parent, but there can be multiple parents (two)// so this is only the parent of the thing we're currently processing.// It is conceptually the same as the return address of a stack frame.// 这条 Fiber 处理完后完后要返回。// 这实际上是 parent,但是可以有多个 parent (两个),所以这只是我们当前正在处理的东西的父类 fiber。// 在概念上与堆栈帧的返回地址相同。return: Fiber | null,// Singly Linked List Tree Structure.// 单链表树结构。child: Fiber | null,sibling: Fiber | null,index: number,// The ref last used to attach this node.// 最后用于附加此节点的 ref。// 我将避免为 prod 和 model 添加一个 owner 字段作为函数。// I'll avoid adding an owner field for prod and model that as functions.ref: null | (((handle: mixed) => void) & {_stringRef: ?string}) | RefObject,// Input is the data coming into process this fiber. Arguments. Props.// 输入是处理该 fiber 的数据。Arguments. Props.pendingProps: any, // This type will be more specific once we overload the tag.一旦我们重载了标签,这种类型将会更加具体。memoizedProps: any, // The props used to create the output.用于创建输出的 props。// A queue of state updates and callbacks.// 状态更新和回调的队列。updateQueue: UpdateQueue<any> | null,// The state used to create the output// 用于创建输出的状态memoizedState: any,// A linked-list of contexts that this fiber depends on// 此 fiber 所依赖的上下文的链表contextDependencies: ContextDependencyList | null,// Bitfield that describes properties about the fiber and its subtree. E.g.// the ConcurrentMode flag indicates whether the subtree should be async-by-// default. When a fiber is created, it inherits the mode of its// parent. Additional flags can be set at creation time, but after that the// value should remain unchanged throughout the fiber's lifetime, particularly// before its child fibers are created.// 位字段,描述 fiber 及其子树的属性。// 例如,ConcurrentMode 标志指示子树是否默认为 async。// 当创建一个 fiber 时,它继承其父的 mode 。// 可以在创建时设置附加标志,但在此之后,值应该在整个 fiber 的生命周期内保持不变,特别是在创建子 fiber 之前。mode: TypeOfMode,// EffecteffectTag: SideEffectTag,// Singly linked list fast path to the next fiber with side-effects.// 单链表快速路径到下一个具有副作用的 fiber。nextEffect: Fiber | null,// The first and last fiber with side-effect within this subtree. This allows// us to reuse a slice of the linked list when we reuse the work done within// this fiber.// 这个子树中的第一个和最后一个有副作用的 fiber。// 这允许我们在重用在这个 fiber 中完成的工作时重用链表的一部分。firstEffect: Fiber | null,lastEffect: Fiber | null,// Represents a time in the future by which this work should be completed.// Does not include work found in its subtree.// 表示将来完成这项工作的时间。// 不包括子树中的工作。expirationTime: ExpirationTime,// This is used to quickly determine if a subtree has no pending changes.// 这用于快速确定子树是否没有挂起的更改。childExpirationTime: ExpirationTime,// This is a pooled version of a Fiber. Every fiber that gets updated will// eventually have a pair. There are cases when we can clean up pairs to save// memory if we need to.// 这是 fiber 的混合版本。// 每一个被更新的 fiber 最终都会有一对。// 在某些情况下,如果需要,我们可以清理它以节省内存。alternate: Fiber | null,// Time spent rendering this Fiber and its descendants for the current update.// This tells us how well the tree makes use of sCU for memoization.// It is reset to 0 each time we render and only updated when we don't bailout.// This field is only set when the enableProfilerTimer flag is enabled.// 为当前更新进行渲染此 fiber 及其后代所花费的时间。// 这告诉我们这棵树如何很好地利用 sCU 进行记忆。// 每次渲染时它都被重置为 0,只有在不进行紧急救援(bailout)时才会更新。// 只有在启用 enableProfilerTimer 标志时才设置此字段。actualDuration?: number,// If the Fiber is currently active in the "render" phase,// This marks the time at which the work began.// This field is only set when the enableProfilerTimer flag is enabled.// 如果 fiber 目前处于“渲染”阶段,// 这标志着这项工作(work)开始的时间。// 只有在启用 enableProfilerTimer 标志时才设置此字段。actualStartTime?: number,// Duration of the most recent render time for this Fiber.// This value is not updated when we bailout for memoization purposes.// This field is only set when the enableProfilerTimer flag is enabled.// 此 fiber 最近渲染的持续时间。// 当我们出于记忆目的进行紧急救助(bailout)时,此值不会更新。// 只有在启用 enableProfilerTimer 标志时才设置此字段。selfBaseDuration?: number,// Sum of base times for all descedents of this Fiber.// This value bubbles up during the "complete" phase.// This field is only set when the enableProfilerTimer flag is enabled.// 这个 fiber 的所有 descedents 的基时间之和。// 这个值在“完成”阶段出现。// 只有在启用 enableProfilerTimer 标志时才设置此字段。treeBaseDuration?: number,// Conceptual 的别名// workInProgress : Fiber ->  alternate// 用于重用的替代方法恰好与正在进行的 work 相同。// 对于复用的替代方法恰好与正在进行的 work 相同。// The alternate used for reuse happens// to be the same as work in progress.// __DEV__ only_debugID?: number,_debugSource?: Source | null,_debugOwner?: Fiber | null,_debugIsCurrentlyTiming?: boolean,// Used to verify that the order of hooks does not change between renders.// 用于验证钩子的顺序在两次渲染之间没有发生变化。_debugHookTypes?: Array<HookType> | null,
|};
复制代码

FiberNode

function FiberNode(tag: WorkTag,pendingProps: mixed,key: null | string,mode: TypeOfMode,
) {// Instancethis.tag = tag;this.key = key;this.elementType = null;this.type = null;this.stateNode = null;// Fiberthis.return = null;this.child = null;this.sibling = null;this.index = 0;this.ref = null;this.pendingProps = pendingProps;this.memoizedProps = null;this.updateQueue = null;this.memoizedState = null;this.contextDependencies = null;this.mode = mode;// Effectsthis.effectTag = NoEffect;this.nextEffect = null;this.firstEffect = null;this.lastEffect = null;this.expirationTime = NoWork;this.childExpirationTime = NoWork;this.alternate = null;if (enableProfilerTimer) {// Note: The following is done to avoid a v8 performance cliff.//// Initializing the fields below to smis and later updating them with// double values will cause Fibers to end up having separate shapes.// This behavior/bug has something to do with Object.preventExtension().// Fortunately this only impacts DEV builds.// Unfortunately it makes React unusably slow for some applications.// To work around this, initialize the fields below with doubles.//// Learn more about this here:// https://github.com/facebook/react/issues/14365// https://bugs.chromium.org/p/v8/issues/detail?id=8538this.actualDuration = Number.NaN;this.actualStartTime = Number.NaN;this.selfBaseDuration = Number.NaN;this.treeBaseDuration = Number.NaN;// It's okay to replace the initial doubles with smis after initialization.// This won't trigger the performance cliff mentioned above,// and it simplifies other profiler code (including DevTools).this.actualDuration = 0;this.actualStartTime = -1;this.selfBaseDuration = 0;this.treeBaseDuration = 0;}if (__DEV__) {// do something}
}
复制代码

createFiber

// This is a constructor function, rather than a POJO constructor, still
// please ensure we do the following:
// 1) Nobody should add any instance methods on this. Instance methods can be
//    more difficult to predict when they get optimized and they are almost
//    never inlined properly in static compilers.
// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
//    always know when it is a fiber.
// 3) We might want to experiment with using numeric keys since they are easier
//    to optimize in a non-JIT environment.
// 4) We can easily go from a constructor to a createFiber object literal if that
//    is faster.
// 5) It should be easy to port this to a C struct and keep a C implementation
//    compatible.
const createFiber = function(tag: WorkTag,pendingProps: mixed,key: null | string,mode: TypeOfMode,
): Fiber {// $FlowFixMe: the shapes are exact here but Flow doesn't like constructorsreturn new FiberNode(tag, pendingProps, key, mode);
};
复制代码

createWorkInProgress

// This is used to create an alternate fiber to do work on.
// 用于创建进行工作的备用 fiber。
export function createWorkInProgress(current: Fiber,pendingProps: any,expirationTime: ExpirationTime,
): Fiber {let workInProgress = current.alternate;if (workInProgress === null) {// We use a double buffering pooling technique because we know that we'll// only ever need at most two versions of a tree. We pool the "other" unused// node that we're free to reuse. This is lazily created to avoid allocating// extra objects for things that are never updated. It also allow us to// reclaim the extra memory if needed.workInProgress = createFiber(current.tag,pendingProps,current.key,current.mode,);workInProgress.elementType = current.elementType;workInProgress.type = current.type;workInProgress.stateNode = current.stateNode;if (__DEV__) {// DEV-only fieldsworkInProgress._debugID = current._debugID;workInProgress._debugSource = current._debugSource;workInProgress._debugOwner = current._debugOwner;workInProgress._debugHookTypes = current._debugHookTypes;}workInProgress.alternate = current;current.alternate = workInProgress;} else {workInProgress.pendingProps = pendingProps;// 我们已经有一个 alternate.// 重置效果标签。workInProgress.effectTag = NoEffect;// The effect list is no longer valid.// 效果列表不再有效。workInProgress.nextEffect = null;workInProgress.firstEffect = null;workInProgress.lastEffect = null;if (enableProfilerTimer) {// We intentionally reset, rather than copy, actualDuration & actualStartTime.// This prevents time from endlessly accumulating in new commits.// This has the downside of resetting values for different priority renders,// But works for yielding (the common case) and should support resuming.workInProgress.actualDuration = 0;workInProgress.actualStartTime = -1;}}workInProgress.childExpirationTime = current.childExpirationTime;workInProgress.expirationTime = current.expirationTime;workInProgress.child = current.child;workInProgress.memoizedProps = current.memoizedProps;workInProgress.memoizedState = current.memoizedState;workInProgress.updateQueue = current.updateQueue;workInProgress.contextDependencies = current.contextDependencies;// These will be overridden during the parent's reconciliationworkInProgress.sibling = current.sibling;workInProgress.index = current.index;workInProgress.ref = current.ref;if (enableProfilerTimer) {workInProgress.selfBaseDuration = current.selfBaseDuration;workInProgress.treeBaseDuration = current.treeBaseDuration;}return workInProgress;
}
复制代码

createHostRootFiber

export function createHostRootFiber(isConcurrent: boolean): Fiber {let mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;if (enableProfilerTimer && isDevToolsPresent) {// Always collect profile timings when DevTools are present.// This enables DevTools to start capturing timing at any point–// Without some nodes in the tree having empty base times.mode |= ProfileMode;}return createFiber(HostRoot, null, null, mode);
}
复制代码

createFiberFromTypeAndProps

/*** 根据 type 和 props 创建 fiber* @param type* @param key* @param pendingProps* @param owner* @param mode* @param expirationTime* @returns {Fiber|*}*/
export function createFiberFromTypeAndProps(type: any, // React$ElementTypekey: null | string,pendingProps: any,owner: null | Fiber,mode: TypeOfMode,expirationTime: ExpirationTime,
): Fiber {let fiber;let fiberTag = IndeterminateComponent;// The resolved type is set if we know what the final type will be. I.e. it's not lazy.let resolvedType = type;if (typeof type === 'function') {if (shouldConstruct(type)) {fiberTag = ClassComponent;}} else if (typeof type === 'string') {fiberTag = HostComponent;} else {getTag: switch (type) {case REACT_FRAGMENT_TYPE:return createFiberFromFragment(pendingProps.children,mode,expirationTime,key,);case REACT_CONCURRENT_MODE_TYPE:return createFiberFromMode(pendingProps,mode | ConcurrentMode | StrictMode,expirationTime,key,);case REACT_STRICT_MODE_TYPE:return createFiberFromMode(pendingProps,mode | StrictMode,expirationTime,key,);case REACT_PROFILER_TYPE:return createFiberFromProfiler(pendingProps, mode, expirationTime, key);case REACT_SUSPENSE_TYPE:return createFiberFromSuspense(pendingProps, mode, expirationTime, key);default: {if (typeof type === 'object' && type !== null) {switch (type.$$typeof) {case REACT_PROVIDER_TYPE:fiberTag = ContextProvider;break getTag;case REACT_CONTEXT_TYPE:// This is a consumerfiberTag = ContextConsumer;break getTag;case REACT_FORWARD_REF_TYPE:fiberTag = ForwardRef;break getTag;case REACT_MEMO_TYPE:fiberTag = MemoComponent;break getTag;case REACT_LAZY_TYPE:fiberTag = LazyComponent;resolvedType = null;break getTag;}}let info = '';if (__DEV__) {if (type === undefined ||(typeof type === 'object' &&type !== null &&Object.keys(type).length === 0)) {info +=' You likely forgot to export your component from the file ' +"it's defined in, or you might have mixed up default and " +'named imports.';}const ownerName = owner ? getComponentName(owner.type) : null;if (ownerName) {info += '\n\nCheck the render method of `' + ownerName + '`.';}}invariant(false,'Element type is invalid: expected a string (for built-in ' +'components) or a class/function (for composite components) ' +'but got: %s.%s',type == null ? type : typeof type,info,);}}}fiber = createFiber(fiberTag, pendingProps, key, mode);fiber.elementType = type;fiber.type = resolvedType;fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromElement

/*** 根据 element 创建 fiber* @param element* @param mode* @param expirationTime* @returns {Fiber}*/
export function createFiberFromElement(element: ReactElement,mode: TypeOfMode,expirationTime: ExpirationTime,
): Fiber {let owner = null;if (__DEV__) {owner = element._owner;}const type = element.type;const key = element.key;const pendingProps = element.props;const fiber = createFiberFromTypeAndProps(type,key,pendingProps,owner,mode,expirationTime,);if (__DEV__) {fiber._debugSource = element._source;fiber._debugOwner = element._owner;}return fiber;
}
复制代码

createFiberFromFragment


/*** 根据 Fragment 创建 Fiber* @param elements* @param mode* @param expirationTime* @param key* @returns {Fiber}*/
export function createFiberFromFragment(elements: ReactFragment,mode: TypeOfMode,expirationTime: ExpirationTime,key: null | string,
): Fiber {const fiber = createFiber(Fragment, elements, key, mode);fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromProfiler

/*** 根据 Profiler 创建 Fiber* @param pendingProps* @param mode* @param expirationTime* @param key* @returns {Fiber}*/
function createFiberFromProfiler(pendingProps: any,mode: TypeOfMode,expirationTime: ExpirationTime,key: null | string,
): Fiber {if (__DEV__) {if (typeof pendingProps.id !== 'string' ||typeof pendingProps.onRender !== 'function') {warningWithoutStack(false,'Profiler must specify an "id" string and "onRender" function as props',);}}const fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);// TODO: The Profiler fiber shouldn't have a type. It has a tag.fiber.elementType = REACT_PROFILER_TYPE;fiber.type = REACT_PROFILER_TYPE;fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromMode

/*** 根据 mode 创建 fiber* @param pendingProps* @param mode* @param expirationTime* @param key* @returns {Fiber}*/
function createFiberFromMode(pendingProps: any,mode: TypeOfMode,expirationTime: ExpirationTime,key: null | string,
): Fiber {const fiber = createFiber(Mode, pendingProps, key, mode);// TODO: The Mode fiber shouldn't have a type. It has a tag.const type =(mode & ConcurrentMode) === NoContext? REACT_STRICT_MODE_TYPE: REACT_CONCURRENT_MODE_TYPE;fiber.elementType = type;fiber.type = type;fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromSuspense

/*** 根据 Suspense 创建 fiber* @param pendingProps* @param mode* @param expirationTime* @param key* @returns {Fiber}*/
export function createFiberFromSuspense(pendingProps: any,mode: TypeOfMode,expirationTime: ExpirationTime,key: null | string,
) {const fiber = createFiber(SuspenseComponent, pendingProps, key, mode);// TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.const type = REACT_SUSPENSE_TYPE;fiber.elementType = type;fiber.type = type;fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromText

/*** 基于文本创建 fiber* @param content* @param mode* @param expirationTime* @returns {Fiber}*/
export function createFiberFromText(content: string,mode: TypeOfMode,expirationTime: ExpirationTime,
): Fiber {const fiber = createFiber(HostText, content, null, mode);fiber.expirationTime = expirationTime;return fiber;
}
复制代码

createFiberFromHostInstanceForDeletion

export function createFiberFromHostInstanceForDeletion(): Fiber {const fiber = createFiber(HostComponent, null, null, NoContext);// TODO: These should not need a type.fiber.elementType = 'DELETED';fiber.type = 'DELETED';return fiber;
}
复制代码

createFiberFromPortal


/*** 创建来自 portal 的fiber* @param portal* @param mode* @param expirationTime* @returns {Fiber}*/
export function createFiberFromPortal(portal: ReactPortal,mode: TypeOfMode,expirationTime: ExpirationTime,
): Fiber {const pendingProps = portal.children !== null ? portal.children : [];const fiber = createFiber(HostPortal, pendingProps, portal.key, mode);fiber.expirationTime = expirationTime;fiber.stateNode = {containerInfo: portal.containerInfo,pendingChildren: null, // Used by persistent updatesimplementation: portal.implementation,};return fiber;
}
复制代码

转载于:https://juejin.im/post/5d1a17d86fb9a07ea803e28f

React 深度学习:ReactFiber相关推荐

  1. React 深度学习:ReactFiberLazyComponent

    path: packages/react-reconciler/src/ReactFiberLazyComponent.js resolveDefaultProps 解析默认 props export ...

  2. React 深度学习:invariant

    path: packages/shared/invariant.js 源码 /*** 根据条件抛出固定格式的错误,允许使用 %s 作为变量的占位符* * @param condition* @para ...

  3. 迁移学习,让深度学习不再困难……

    2020-03-02 17:01:00 全文共2968字,预计学习时长9分钟 来源:Pexels 在不远的过去,数据科学团队需要一些东西来有效地利用深度学习: · 新颖的模型架构,很可能是内部设计的 ...

  4. “深度学习一点也不难!”

    2020-02-14 11:11:15 通常情况下,机器学习尤其是深度学习的使用往往需要具备相当的有利条件,包括一个大型的数据集,设计有效的模型,而且还需要训练的方法--但现在,利用迁移学习就可以消除 ...

  5. 深度学习:在图像上找到手势_使用深度学习的人类情绪和手势检测器:第2部分

    深度学习:在图像上找到手势 情感手势检测 (Emotion Gesture Detection) Hello everyone! Welcome back to the part-2 of human ...

  6. 机器学习 深度学习 ai_人工智能,机器学习,深度学习-特征和差异

    机器学习 深度学习 ai Artificial Intelligence (AI) will and is currently taking over an important role in our ...

  7. 如何在TensorFlow中通过深度学习构建年龄和性别的多任务预测器

    by Cole Murray 通过科尔·默里(Cole Murray) In my last tutorial, you learned about how to combine a convolut ...

  8. 深度学习去燥学习编码_通过编码学习编码

    深度学习去燥学习编码 "Teach Yourself to program in 10 years." That's how Peter Norvig - a Berkeley p ...

  9. 媒智科技--深度学习算法Python后台开发--热招中~

    点击我爱计算机视觉标星,更快获取CVML新技术 公司简介 媒智科技源起于上海交通大学,核心团队由上海交大.清华.斯坦福.乔治亚理工等顶尖高校的人工智能教授,以及来自雅虎.腾讯等科技精英组成,聚焦计算机 ...

最新文章

  1. 马斯克突然抢购7千多万股推特,狂撒30亿一夜成最大股东,今日发推“大笑”...
  2. 微软软件推送服务器,向 UWP 应用添加推送通知 - Azure Mobile Apps | Microsoft Docs
  3. 直正的互联网产品设计:七个作为产品经理实际上很重要的”小事“
  4. 04. Web大前端时代之:HTML5+CSS3入门系列~HTML5 表单
  5. :)xception_Xception:认识Xtreme盗梦空间
  6. Python档案袋( 面向对象 )
  7. cf1512 G - Short Task
  8. JavaWeb 如何防止表单重复提交 - 使用Token,令牌
  9. powerdesigner逆向工程(sql转pdm)
  10. Fortran 95 流程控制、循环
  11. VS2017+AE10.2实现二次开发
  12. bp神经网络的训练方法,一文搞定bp神经网络
  13. svn拉取文件合并_svn 创建分支、合并分支、分支与分支合并
  14. 无人驾驶综述:国外国内发展历程
  15. mac过热_如何阻止Mac过热
  16. 多测师杭州拱墅校区__肖sir__软件测试生命周期(4)
  17. 深度学习图像标签标注软件labelme超详细教程
  18. 离散数学 08.02 格的定义
  19. 神经网络压缩库 Distiller
  20. 免费送!!!CSDN 会员月卡!

热门文章

  1. Asp.net页面生存周期
  2. htc g7 android 4.4,HTC G7刷机,从WM手机刷到了安卓,开启了新的刷机体验....
  3. python读取hdf5文件_Python处理HDF5文件
  4. 广联达2018模板算量步骤_广联达gtj2021实操案例,新增6大板块,快速提高算量效率...
  5. android webview sql database,websql在openDatabase报version mismatch错误,请问怎么解决?
  6. linux怎么进入文件夹_Linux基础命令《上》
  7. 位置服务器管理器,查看 DIMM 位置
  8. Command mysql 中文,MySQL Command Line[mysql命令行常用命令]_MySQL
  9. 《YOLO算法笔记》(草稿)
  10. java 方法 示例_Java Collectionsfrequency()方法与示例