import { ReactElement } from '../shared/ReactTypes' ; import { Fiber } from './ReactInternalTypes' ; import { ConcurrentRoot , RootTag } from './ReactRootTags' ; import { WorkTag , HostRoot , IndeterminateComponent , HostComponent , HostText , MemoComponent , } from './ReactWorkTags' ; import { BlockingMode , ConcurrentMode , NoMode , TypeOfMode , } from './ReactTypeOfMode' ; import { Flags , NoFlags } from './ReactFiberFlags' ; import { Lanes , NoLanes } from './ReactFiberLane' ; import { REACT_MEMO_TYPE } from '../shared/ReactSymbols' ; /**
 * 属性含义可查看react-reconciler\ReactInternalTypes.ts
 * 下的Fiber Type
 */ class FiberNode { stateNode : any = null ; updateQueue : unknown = null ; return : Fiber | null = null ; alternate : Fiber | null = null ; memoizedState : any = null ; child : Fiber | null = null ; sibling : Fiber | null = null ; type : any = null ; memoizedProps : any = null ; flags : Flags = 0 ; subtreeFlags : Flags = 0 ; deletions : Fiber [ ] | null = null ; index : number = 0 ; lanes = NoLanes ; childLanes = NoLanes ; elementType = null ; constructor ( public tag , public pendingProps , public key , public mode ) { } } param tag returns export const createHostRootFiber = ( tag ) : Fiber => { let mode ; if ( tag === ConcurrentRoot ) { mode = ConcurrentMode | BlockingMode ; } else { mode = NoMode ; } return new FiberNode ( HostRoot , null , null , mode ) ; } ; param tag param pendingProps param key param mode returns export const createFiber = ( tag , pendingProps , key , mode ) => { return new FiberNode ( tag , pendingProps , key , mode ) ; } ; param current param pendingProps export const createWorkInProgress = ( current , pendingProps ) : Fiber => { let workInProgress = current . alternate ; if ( workInProgress === null ) { /**
         * 考虑下面的App组件，帮你理解上面的话
         * const TriggerUpdate = () => {
         *   const [count, setCount] = useState(0)
         *
         *   return (
         *     <div>
         *       {count}
         *       <button
         *         onClick={() => {
         *           setCount(count + 1)
         *         }}
         *       >
         *         increment
         *       </button>
         *     </div>
         *   )
         * }
         *
         * const App = () => {
         *  return (
         *    <div id="container">
         *      <div style={{
         *         background: 'red',
         *        }}
         *        id="static"
         *      >
         *        Static Node
         *        <div>Static Node</div>
         *      </div>
         *      <TriggerUpdate />
         *    </div>
         *  )
         *}
         * 下面会使用jquery选择器的方式指明我们说的时哪个fiber节点
         * 比如$('#container')就表示哪个id为container的div所对应的fiber
         * 虽然App中的TriggerUpdate会触发更新但是他冒泡的lanes
         * 并不会影响到并不在他冒泡路径上和他同级的
         * $('#static')节点所以他的lanes和childLanes一直都是NoLanes，
         * 因为也知道他的父级节点$('#container') div也没有更新，
         * 所以在创建$('#static') div节点时复用前一次的props，
         * 当接下来进行$('#static')的beginWork时，由于前后props没变且不包含lanes
         * 会执行他的bailoutOnAlreadyFinishedWork逻辑
         * 即使此次更新中$('#static')对应的jsx对象的style属性是全新的对象，
         * 在执行bailout逻辑中发现他的childLanes为NoLanes所以直接返回，不在复制他的child
         * 进行render工作了，所以$('#static')节点的子节点只有在首次mount时会被创建一次，
         * 对于这些静态节点，在整个过程中，两颗fiber树始终指向相同的对象
         */ workInProgress = createFiber ( current . tag , pendingProps , current . key , current . mode ) ; workInProgress . elementType = current . elementType ; workInProgress . type = current . type ; workInProgress . stateNode = current . stateNode ; workInProgress . alternate = current ; current . alternate = workInProgress ; } else { workInProgress . pendingProps = pendingProps ; workInProgress . type = current . type ; workInProgress . flags = NoFlags ; workInProgress . subtreeFlags = NoFlags ; workInProgress . deletions = null ; } workInProgress . lanes = current . lanes ; workInProgress . updateQueue = current . updateQueue ; workInProgress . childLanes = current . childLanes ; workInProgress . flags = current . flags ; workInProgress . child = current . child ; workInProgress . memoizedProps = current . memoizedProps ; workInProgress . memoizedState = current . memoizedState ; return workInProgress ; } ; param type param key param pendingProps param mode param lanes returns export const createFiberFromTypeAndProps = ( type , key , pendingProps , mode , lanes ) => { let fiberTag = IndeterminateComponent ; let resolvedType = type ; if ( typeof type === 'function' ) { } else if ( typeof type === 'string' ) { fiberTag = HostComponent ; } else { getTag : switch ( type ) { default : { if ( typeof type === 'object' && type !== null ) { switch ( type . $$typeof ) { case REACT_MEMO_TYPE : { fiberTag = MemoComponent ; break getTag ; } default : { throw new Error ( 'Not Implement' ) ; } } } else { throw new Error ( 'Not Implement' ) ; } } } } const fiber = createFiber ( fiberTag , pendingProps , key , mode ) ; fiber . type = resolvedType ; fiber . lanes = lanes ; fiber . elementType = type ; return fiber ; } ; export const createFiberFromElement = ( element , mode , lanes ) : Fiber => { const type = element . type ; const key = element . key as any ; const pendingProps = element . props ; const fiber = createFiberFromTypeAndProps ( type , key , pendingProps , mode , lanes ) ; return fiber ; } ; param content param mode returns export const createFiberFromText = ( content , mode , lanes ) : Fiber => { const fiber = createFiber ( HostText , content , null , mode ) ; fiber . lanes = lanes ; return fiber ; } ; export const isSimpleFunctionComponent = ( type ) : boolean => { return typeof type === 'function' && type . defaultProps === undefined ; } ;