卖设备用哪个网站,网站后台服务器内部错误,虾米wordpress插件,在线商城网站开发代码关于 Fiber 对象
在FiberRoot里面#xff0c;它也会为我们去创建的一个对象叫做 Fiber在 React16 之后, 非常核心#xff0c;非常重要的一个东西A. 每个 ReactElement 都会对应一个 Fiber 对象B. 它会记录节点的各种状态 比如#xff0c;class component#xff0c;它的st…关于 Fiber 对象
在FiberRoot里面它也会为我们去创建的一个对象叫做 Fiber在 React16 之后, 非常核心非常重要的一个东西A. 每个 ReactElement 都会对应一个 Fiber 对象B. 它会记录节点的各种状态 比如class component它的state和props这些东西是记录在 Fiber 对象上面的在 Fiber 更新之后才会更新到 class component 上面的 this.state, this.props 里面并不是通过 class component 自己去调理的这个过程这些过程都是在 Fiber 上面进行操作的只是在更新了这个节点之后它才会把这个属性放到this上面因此也给了react实现 hooks 一个方便因为hooks是用在function component里面的里面没有this我们本身记录state还有props都不是在class component的对象上面而是在 Fiber 上面我们有能力记录这个状态之后也可以让function component更新的过程当中去拿到这个更新之后的state所以Fiber有一个非常重要的作用就是记录节点的各种状态 C. 串联整个应用 在 ReactElement 中通过 props.children 属性把整个应用串联起来每一个节点都可以通过一个属性去拿到它的子节点在 Fiber 里面它也是有这么一个能力来帮助我们记录整个应用的一个树形结构的一个状态把每一个节点给它串联起来在 Fiber 里面它是如何进行一个串联的呢需要先回顾一下 ReactElement 的串联方式, 结合前文中的举例如下 App|render() return|div/ \/ \children[0] children[1]/ \/ \/ \Input List| \
render() return render() return | \input (span span span button)上面就是 ReactElement 基于 render() 函数 return 了子节点由此构建的树形结构Fiber 里面也有这个能力记录整个应用的树形结构和状态把每个节点串联起来 -----current----- FiberRoot RootFiber---stateNode----- | |child |↓App|child|↓|div/ \/ \child child/ \/ \/ \Input-sibling- List| \child child| \↓ \input span --sibling-- span --sibling-- span --sibling-- button被首先创建的 FiberRoot 有一个 current 属性指向一个 Fiber对象我们叫做 RootFiber因为 FiberRoot 在 ReactDOM.render 时接受了 一个参数是 AppApp 这个 ReactElement 它对应的Fiber对象就是 RootFiber 的 childApp 的 child 就是 div 节点因为它的 render 函数渲染出来之后就是一个 div 的唯一子节点这个 div 接收到的 props.children 是一个数组这个数组的第一个节点会作为它的 child, 其指向 Input 组件对应的 Fiber对象List 也是作为 div的 props.children 的一项它是 Input 对应Fiber对象的 sibling 兄弟节点也就是说每个节点只会存储它的第一个子节点不会把它的子节点都存放在一起通过上述单项的指向来进行存储对于 Input 组件来说它的 child 就是其 render 函数 return 的一个 input 原生标签对于 List 组件来说它返回的是一个数组它的第一个子节点就是 span, 剩下的兄弟节点通过 sibling 来连接而每个子节点都会有一个 return 属性指向自己的父节点上述图示中并没有标示出来我们进行节点的查找就会非常方便只需要通过 child 一路向下查找直接到叶子节点基于这种方式来遍历整个应用即通过react的这种数据结构把整个 Fiber树给它串联起来提供给我们一个方便高效的遍历方式现在看下 Fiber 的属性源码在: https://github.com/facebook/react/blob/v16.6.0/packages/react-reconciler/src/ReactFiber.js// A Fiber is work on a Component that needs to be done or was done. There can
// be more than one per component.
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, weve merged them into a// single type.// 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.// Tag identifying the type of fiber.tag: WorkTag, // 标记不同的组件类型有原生dom节点的组件, 有 class component, function component, 各种各样的组件都有对应的类型// Unique identifier of this child.key: null | string, // ReactElement 里面的key// The value of element.type which is used to preserve the identity during// reconciliation of this child.elementType: any, // ReactElement.type, 就是调用 createElement 的第一个参数// The resolved function/class/ associated with this fiber.type: any, // 异步组件 resolved 之后返回的内容, 一般是 function 或 class// The local state associated with this fiber.stateNode: any, // 跟当前Fiber相关的本地状态在浏览器环境中就是DOM节点对应节点实际的实例比如 class component 对应 class 的实例, dom组件对应dom节点的实例function component 没有实例就没有 stateNode, 有了它在应用更新完成后就可以把 最新的 stateprops 等放到节点上// Conceptual aliases// parent : Instance - return The parent happens to be the same as the// return fiber since weve merged the fiber and instance.// Remaining fields belong to 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 were currently processing.// It is conceptually the same as the return address of a stack frame.return: Fiber | null,// Singly Linked List Tree Structure.child: Fiber | null,sibling: Fiber | null,index: number,// The ref last used to attach this node.// Ill avoid adding an owner field for prod and model that as functions.ref: null | (((handle: mixed) void) {_stringRef: ?string}) | RefObject, // ref 属性// Input is the data coming into process this fiber. Arguments. Props.pendingProps: any, // This type will be more specific once we overload the tag. // 新的变动带来的新的 props就存在 pendingProps 属性上memoizedProps: any, // The props used to create the output. // 上一次更新结束之后的 props// A queue of state updates and callbacks.updateQueue: UpdateQueueany | null, // 该 Fiber 对应的组件产生的 update 会存放在这个队列里面// The state used to create the outputmemoizedState: any, // 上次渲染完成之后的 state比如我们执行setState会算出一个新的state算出是要经过 updateQueue计算的, 计算完之后覆盖 memoizedState 值// A linked-list of contexts that this fiber depends onfirstContextDependency: ContextDependencymixed | null, // 一个列表存放这个Fiber依赖的context// 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 fibers lifetime, particularly// before its child fibers are created.mode: TypeOfMode, // 用于描述当前Fiber和它子树的Bitfield, 共存的模式表示这个子树是否默认是异步渲染的, Fiber 被创建的时候会继承父Fiber, 其他的标识也可以在创建的时候被设置但在创建之后不应该再被修改特别是他的子Fiber创建之前 对应比如: ConcurrentMode, StrictMode,// EffecteffectTag: SideEffectTag, // 副作用用来记录 Side Effect// Singly linked list fast path to the next fiber with side-effects.nextEffect: Fiber | null, // 副作用 单链表用来快速查找下一个 side effect// 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.firstEffect: Fiber | null, // 副作用子树中第一个 side effectlastEffect: Fiber | null, // 副作用子树中最后一个 side effect// 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.alternate: Fiber | null, // 在Fiber树更新的过程中每个Fiber都会有一个跟其对应的Fiber,我们称它为 current workInProgress的对应关系, 在渲染完成之后他们会交换位置在更新过程中会根据整个Fiber对象创建一个 workInProgress, current是当前的 workInProgress 是要进行一个更新的, 在更新完成后workInProgress 状态会更新成一个新的current就变成老的最终节点渲染到 dom 上面workInProgress 会变成current再下一次更新到来的时候会保持着两个对象都存在这个在 react 中叫做 double buffer, 是用来提高性能的// 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 dont bailout.// This field is only set when the enableProfilerTimer flag is enabled.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.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.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.treeBaseDuration?: number,// Conceptual aliases// workInProgress : Fiber - alternate 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,
|};Fiber里面三个重要的属性: return, child, sibling 可以帮助把应用中的所有节点一一串联 return: 指向它在Fiber节点树中的 parent, 用来处理完这个节点之后向上返回child: 单链表树结构, 指向自己的第一个子节点sibling: 指向自己的兄弟结构兄弟节点的return指向同一个父节点 上述 Effect 相关的属性都是副作用是用来标记 Dom 节点要进行那些更新的工具以及标记是否要执行组件生命周期的内容上述 Duration 相关属性是渲染时间相关的和 React DEV TOOL 有相关关系其他属性都在代码中备注