A presentation at Reactathon in March 2019 in San Francisco, CA, USA by Jenn Creighton
Everything I know about React I learned from Twitter Jenn Creighton (@gurlcode) FrontEnd Engineer @ Rent the RunwaY
React Detective ! @gurlcode
On a dark & stormy night… @gurlcode
@gurlcode
🔎 @gurlcode
Welcome! @gurlcode
React.createElement(”button”, null); @gurlcode
React Element { type: button, props: { … } } @gurlcode
Fiber { tag child sibling return … } @gurlcode
Fiber { Fiber type tag child sibling return … } @gurlcode
Fiber { Child fiber Fiber type tag child sibling return … } @gurlcode
Fiber { Child fiber Fiber type tag child sibling return … Sibling fiber } @gurlcode
Fiber { Child fiber Parent fiber Fiber type tag child sibling return … Sibling fiber } @gurlcode
reactInternalInstance @gurlcode
div h1 C div one-way two-way @gurlcode
ReactDOM.unstable_createRoot(node) @gurlcode
new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
createFiberRoot new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
createHostRootFiber createFiberRoot new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
HostRoot createFiber fiber { tag: HostRoot } createFiberRoot new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
HostRoot createFiber root.current = fiber new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
HostRoot createFiber new ReactRoot ReactDOM.unstable_createRoot(node) @gurlcode
HostRoot createFiber this._internalRoot = root ReactDOM.unstable_createRoot(node) @gurlcode
HostRoot createFiber root = ReactRoot @gurlcode
this._InternalRoot { current: { tag: HostRoot } … } @gurlcode
HostRoot root.render( ReactElement ) @gurlcode
HostRoot ReactRoot.render( ReactElement ) @gurlcode
HostRoot scheduleRootUpdate(current, element) ReactRoot.render( ReactElement ) @gurlcode
HostRoot update = { element: element } ReactRoot.render( ReactElement ) @gurlcode
HostRoot enqueueUpdate(update) scheduleRootUpdate(current, element) ReactRoot.render( ReactElement ) @gurlcode
Fiber { alternate tag child sibling list of state updates return updateQueue } @gurlcode
HostRoot scheduleWork( ) scheduleWork scheduleRootUpdate(current, element) ReactRoot.render( ReactElement ) @gurlcode
HostRoot performWork @gurlcode
HostRoot renderRoot performWork @gurlcode
HostRoot createWorkInProgress(current) renderRoot performWork @gurlcode
HostRoot workInProgress = current.alternate renderRoot performWork @gurlcode
Fiber { Pooled fiber alternate tag child sibling return … } @gurlcode
HostRoot workInProgress === null renderRoot performWork @gurlcode
HostRoot createFiber(current) workInProgress = current.alternate renderRoot performWork @gurlcode
HostRoot current.alternate = workInProgress renderRoot performWork @gurlcode
HostRoot nextUnitOfWork = workInProgress performWork @gurlcode
HostRoot workLoop nextUnitOfWork = workInProgress performWork @gurlcode
fiber @gurlcode
HostRoot workLoop @gurlcode
HostRoot performUnitOfWork workLoop @gurlcode
HostRoot beginWork performUnitOfWork workLoop @gurlcode
HostRoot updateHostRoot beginWork performUnitOfWork workLoop @gurlcode
HostRoot processUpdateQueue updateHostRoot beginWork performUnitOfWork workLoop @gurlcode
HostRoot newState = { element: element } updateHostRoot beginWork performUnitOfWork workLoop @gurlcode
HostRoot fiber.memoizedState = newState updateHostRoot beginWork performUnitOfWork workLoop @gurlcode
Fiber { alternate tag child sibling return memoizedState … current state } @gurlcode
HostRoot nextChild = fiber.memoizedState.element beginWork performUnitOfWork workLoop @gurlcode
HostRoot reconcileChildFibers(child, nextChild) nextChild = fiber.memoizedState.element beginWork performUnitOfWork workLoop @gurlcode
HostRoot workInProgress.child = createFiber( ) div nextChild = fiber.memoizedState.element beginWork performUnitOfWork workLoop @gurlcode
HostRoot div return workInProgress.child beginWork performUnitOfWork workLoop @gurlcode
HostRoot div return workInProgress.child performUnitOfWork workLoop @gurlcode
HostRoot div return workInProgress.child workLoop @gurlcode
HostRoot div nextUnitOfWork = performUnitWork @gurlcode
HostRoot div nextUnitOfWork !== null @gurlcode
HostRoot div workLoop @gurlcode
HostRoot div performUnitOfWork workLoop @gurlcode
HostRoot div beginWork performUnitOfWork workLoop @gurlcode
HostRoot div updateHostComponent beginWork performUnitOfWork workLoop @gurlcode
HostRoot div nextChild = fiber.pendingProps.children beginWork performUnitOfWork workLoop @gurlcode
Fiber { alternate tag child sibling return memoizedState pendingProps … waiting to be applied } @gurlcode
HostRoot reconcileChildFibers(child, nextChild) div updateHostComponent beginWork performUnitOfWork workLoop @gurlcode
reconcileChildrenArray reconcileChildFibers HostRoot div updateHostComponent beginWork performUnitOfWork workLoop @gurlcode
HostRoot child = createFiber( ) reconcileChildFibers div updateHostComponent h1 beginWork performUnitOfWork workLoop @gurlcode
HostRoot child.sibling = createFiber( ) reconcileChildFibers div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot return child reconcileChildFibers div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot workInProgress.child = child div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot div return workInProgress.child h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot div h1 C return workInProgress.child performUnitOfWork workLoop @gurlcode
HostRoot div h1 C return workInProgress.child workLoop @gurlcode
HostRoot div h1 C nextUnitOfWork = performUnitWork @gurlcode
HostRoot div h1 C nextUnitOfWork !== null @gurlcode
HostRoot div h1 C workLoop @gurlcode
HostRoot div h1 C performUnitOfWork workLoop @gurlcode
HostRoot div h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot reconcileChildFibers div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot workInProgress.child = null div updateHostComponent h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot div return null h1 C beginWork performUnitOfWork workLoop @gurlcode
HostRoot div h1 C return null performUnitOfWork workLoop @gurlcode
HostRoot div h1 C nextUnitOfWork === null workLoop @gurlcode
HostRoot div h1 C completeUnitOfWork performUnitOfWork workLoop @gurlcode
HostRoot div completeWork h1 C completeUnitOfWork return performUnitOfWork workInProgress.child workLoop @gurlcode
HostRoot div return fiber.sibling | | fiber.return h1 C completeUnitOfWork return performUnitOfWork workInProgress.child workLoop @gurlcode
HostRoot div h1 C return fiber.sibling return performUnitOfWork workInProgress.child workLoop @gurlcode
HostRoot div h1 C return fiber.sibling return return workInProgress.child fiber.sibling workLoop @gurlcode
HostRoot div h1 C return fiber.sibling nextUnitOfWork = performUnitOfWork return workInProgress.child nextUnitOfWork = performUnitOfWork @gurlcode
HostRoot div h1 C @gurlcode
HostRoot div h1 C div @gurlcode
Component.prototype.setState @gurlcode
HostRoot div h1 C div enqueueSetState(fiber, update) @gurlcode
HostRoot div h1 enqueueUpdate(fiber, update) C div enqueueSetState(fiber, update) @gurlcode
HostRoot div h1 scheduleWork( ) C div enqueueSetState(fiber, update) @gurlcode
HostRoot div h1 C div performWork @gurlcode
HostRoot div h1 renderRoot C div performWork @gurlcode
HostRoot div h1 C workInProgress = current.alternate renderRoot div performWork @gurlcode
HostRoot div h1 nextUnitOfWork = workInProgress C div performWork @gurlcode
HostRoot div h1 C workLoop nextUnitOfWork = workInProgress div performWork @gurlcode
HostRoot div h1 C div workLoop @gurlcode
HostRoot div h1 performUnitOfWork C div workLoop @gurlcode
HostRoot div h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot div h1 C oldProps !== newProps performUnitOfWork div workLoop @gurlcode
HostRoot div h1 C return workInProgress.child performUnitOfWork div workLoop @gurlcode
HostRoot div h1 return workInProgress.child C div workLoop @gurlcode
HostRoot div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot updateClassInstance div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot processUpdateQueue updateClassInstance div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot fiber.memoizedState = newState updateClassInstance div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot div instance.state = fiber.memoizedState h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot div nextChild = instance.render( ) h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot reconcileChildFibers div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot fiber.effectTag = Update div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
Fiber { work to be done alternate tag child sibling return memoizedState pendingProps effectTag … } @gurlcode
HostRoot return workInProgress.child div updateClassComponent h1 C beginWork performUnitOfWork div workLoop @gurlcode
HostRoot div return workInProgress.child h1 C beginWork performUnitOfWork div workLoop @gurlcode
div h1 C div @gurlcode
f f f f @gurlcode
VDOM @gurlcode
fn fn fn @gurlcode
When a function is called, a new stack frame is added fn fn fn fn @gurlcode
Fibers are virtual stack frames fiber fiber fiber fiber @gurlcode
Thank You! Huge shoutout to the React core team 💛 @gurlcode