(1) Each ReactElement corresponds to a Fiber object
Fiber objects are used to record various node states, such as state and props in ClassComponent.
Only when the Fiber object is updated will it be updated to this.state and this.props on the ClassComponent
this
On thestate
andprops
Is based onFiber
The object’sstate
,props
The updated.
This actually makes it easier for ReactHooks as hooks serve FunctionalComponent. Although FunctionalComponent does not have this, Fiber does, so it can get state and props
(3) The whole application is connected to form a tree structure. Each ReactElement is connected to other ReactElement through props. Children
ReactElement uses only the first child of the props. Children as a child, and all the other children (siblings of the first child) are connected unidirectionally from the first child to the next sibling
② Each child node points to the parent node (red arrow), which is the return property of the Fiber object
export type Fiber = {|
// Point to the object 'parent' in the Fiber tree to return after processing the node
// The red line on the flow chart
return: Fiber | null.
}
Copy the code
Series process: (1) For any leaf node A, if there is A sibling node, it traverses the sibling node backwards in one direction. If the child node of the parent node is not the child node A, it traverses the node before the parent node from the child node to the parent node, and returns the parent node again to perform ① and ②
For example, if you start from the input node in the lower left corner and it has no siblings, you return to the parent component input (because there is only one parent, you must return to the parent node).
Input has a List of sibling nodes, and the List has a child node. If Input has a List of sibling nodes, return the List from the child node through the sibling node
List returns to div, whose child node has been traversed, and returns to App, which in turn returns to the RootFiber object of all Fiber objects
So we’re done iterating through the entire application.
Fiber object source code:
// A Fiber is work on a Component that needs to be done or was done. There can
// be more than one per component.
//Fiber corresponds to a component that is about to be updated or has been updated,
// A component can have one or more fibers
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.
// 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.
// Mark different component types
React has its own nodes
tag: WorkTag,
// Unique identifier of this child.
//ReactElement key
key: null | string,
// The value of element.type which is used to preserve the identity during
// reconciliation of this child.
//ReactElement. Type is the first parameter we call createElement
elementType: any,
// The resolved function/class/ associated with this fiber.
// What is returned after the asynchronous component resolve, typically function or class
// For example, lazy loading
type: any,
// The local state associated with this fiber.
// The current state of Fiber (e.g. the browser environment is the DOM node)
// Different types of instances are recorded on stateNode
For example, a DOM component corresponds to a DOM node instance
//ClassComponent corresponds to the Class instance
//FunctionComponent has no instance, so stateNode is null
// Props is updated to the stateNode
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.
// 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 we're currently processing.
// It is conceptually the same as the return address of a stack frame.
// Point to the object 'parent' in the Fiber tree to return after processing the node
// The red line on the flow chart
return: Fiber | null.
// Singly Linked List Tree Structure.
// Single list tree structure
// point to your first child node
child: Fiber | null.
// Point to your sibling structure
// Sibling returns refer to the same parent node
sibling: Fiber | null.
index: number,
// The ref last used to attach this node.
// I'll avoid adding an owner field for prod and model that as functions.
/ / ref attribute
ref: null| (((handle: mixed) => void) & {_stringRef: ? string}) | RefObject,
// Input is the data coming into process this fiber. Arguments. Props.
// New changes bring new props, that is, nextProps
pendingProps: any, // This type will be more specific once we overload the tag.
// Props after the last rendering
memoizedProps: any, // The props used to create the output.
// A queue of state updates and callbacks.
// Updates generated by components of this Fiber are placed in this queue
updateQueue: UpdateQueue<any> | null.
// The state used to create the output
// Last rendered state, i.e., state
// The new state is calculated by Update Value and overwrites memoizedState
memoizedState: any,
// Dependencies (contexts, events) for this fiber, if it has any
// A list of contexts, Events dependent on this Fiber
dependencies: Dependencies | 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.
//mode has conCurrentMode and strictMode
// The Bitfield that describes the current Fiber and other subtrees
// The coexistence mode indicates whether the subtree is rendered asynchronously by default
// When Fiber is first created, it inherits its parent Fiber
// Other flags can also be set at creation time, but should not be changed after creation, especially before its sub-fiber is created
mode: TypeOfMode,
// These attributes are side effects
// Side effects are tools to mark which components need to be updated and which lifecycle tools to mark which components need to perform
// Effect
effectTag: SideEffectTag,
// Singly linked list fast path to the next fiber with side-effects.
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.
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.
// represents the point in the future at which the task should be completed
// Do not include tasks generated by the subtree of this Fiber
expirationTime: ExpirationTime,
// This is used to quickly determine if a subtree has no pending changes.
// Quickly determine if there is update in the subtree
// If the child node has an update, record the time when it should be updated
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.
// In the FIber tree update process, each FIber has its corresponding FIber
// We call this current <==> workInProgress
// After rendering is complete, positions will be swapped
// If you update the doubleBuffer Fiber, you don't need to re-create the object.
// Instead of copying itself, the two can be reused to improve performance
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.
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,
_debugNeedsRemount? : boolean,
// Used to verify that the order of hooks does not change between renders.
_debugHookTypes? :Array<HookType> | null.
|};
Copy the code
Fiber is a Fiber that is connected to the React interface. Fiber is a Fiber that is connected to the React interface.
Making: github.com/AttackXiaoJ…
(1) Three functions of Fiber (2) unidirectional traversal (3) children connection (4) child reference (5) doubleBuffer
(after)