diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index ec1d78af03..4de8ce2d5b 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -14,6 +14,7 @@ import type { ReactCoroutine } from 'ReactCoroutine'; import type { Fiber } from 'ReactFiber'; +import type { HostConfig } from 'ReactFiberReconciler'; var ReactChildFiber = require('ReactChildFiber'); var ReactTypeOfWork = require('ReactTypeOfWork'); @@ -33,211 +34,217 @@ var { } = require('ReactPriorityLevel'); var { findNextUnitOfWorkAtPriority } = require('ReactFiberPendingWork'); -function reconcileChildren(current, workInProgress, nextChildren) { - const priority = workInProgress.pendingWorkPriority; - workInProgress.child = ReactChildFiber.reconcileChildFibers( - workInProgress, - current ? current.child : null, - nextChildren, - priority - ); -} +module.exports = function(config : HostConfig) { -function updateFunctionalComponent(current, workInProgress) { - var fn = workInProgress.type; - var props = workInProgress.pendingProps; - console.log('update fn:', fn.name); - var nextChildren = fn(props); - reconcileChildren(current, workInProgress, nextChildren); - workInProgress.pendingWorkPriority = NoWork; -} - -function updateHostComponent(current, workInProgress) { - console.log('host component', workInProgress.type, typeof workInProgress.pendingProps.children === 'string' ? workInProgress.pendingProps.children : ''); - - var nextChildren = workInProgress.pendingProps.children; - - let priority = workInProgress.pendingWorkPriority; - if (workInProgress.pendingProps.hidden && priority !== OffscreenPriority) { - // If this host component is hidden, we can reconcile its children at - // the lowest priority and bail out from this particular pass. Unless, we're - // currently reconciling the lowest priority. - workInProgress.child = ReactChildFiber.reconcileChildFibers( - workInProgress, - current ? current.child : null, - nextChildren, - OffscreenPriority - ); - workInProgress.pendingWorkPriority = OffscreenPriority; - return null; - } else { + function reconcileChildren(current, workInProgress, nextChildren) { + const priority = workInProgress.pendingWorkPriority; workInProgress.child = ReactChildFiber.reconcileChildFibers( workInProgress, current ? current.child : null, nextChildren, priority ); + } + + function updateFunctionalComponent(current, workInProgress) { + var fn = workInProgress.type; + var props = workInProgress.pendingProps; + console.log('update fn:', fn.name); + var nextChildren = fn(props); + reconcileChildren(current, workInProgress, nextChildren); workInProgress.pendingWorkPriority = NoWork; - return workInProgress.child; } -} -function mountIndeterminateComponent(current, workInProgress) { - var fn = workInProgress.type; - var props = workInProgress.pendingProps; - var value = fn(props); - if (typeof value === 'object' && value && typeof value.render === 'function') { - console.log('performed work on class:', fn.name); - // Proceed under the assumption that this is a class instance - workInProgress.tag = ClassComponent; - if (workInProgress.alternate) { - workInProgress.alternate.tag = ClassComponent; - } - } else { - console.log('performed work on fn:', fn.name); - // Proceed under the assumption that this is a functional component - workInProgress.tag = FunctionalComponent; - if (workInProgress.alternate) { - workInProgress.alternate.tag = FunctionalComponent; + function updateHostComponent(current, workInProgress) { + console.log('host component', workInProgress.type, typeof workInProgress.pendingProps.children === 'string' ? workInProgress.pendingProps.children : ''); + + var nextChildren = workInProgress.pendingProps.children; + + let priority = workInProgress.pendingWorkPriority; + if (workInProgress.pendingProps.hidden && priority !== OffscreenPriority) { + // If this host component is hidden, we can reconcile its children at + // the lowest priority and bail out from this particular pass. Unless, we're + // currently reconciling the lowest priority. + workInProgress.child = ReactChildFiber.reconcileChildFibers( + workInProgress, + current ? current.child : null, + nextChildren, + OffscreenPriority + ); + workInProgress.pendingWorkPriority = OffscreenPriority; + return null; + } else { + workInProgress.child = ReactChildFiber.reconcileChildFibers( + workInProgress, + current ? current.child : null, + nextChildren, + priority + ); + workInProgress.pendingWorkPriority = NoWork; + return workInProgress.child; } } - reconcileChildren(current, workInProgress, value); - workInProgress.pendingWorkPriority = NoWork; -} -function updateCoroutineComponent(current, workInProgress) { - var coroutine = (workInProgress.pendingProps : ?ReactCoroutine); - if (!coroutine) { - throw new Error('Should be resolved by now'); - } - console.log('begin coroutine', workInProgress.type.name); - reconcileChildren(current, workInProgress, coroutine.children); - workInProgress.pendingWorkPriority = NoWork; -} - -function reuseChildren(returnFiber : Fiber, firstChild : Fiber) { - // TODO: None of this should be necessary if structured better. - // The returnFiber pointer only needs to be updated when we walk into this child - // which we don't do right now. If the pending work priority indicated only - // if a child has work rather than if the node has work, then we would know - // by a single lookup on workInProgress rather than having to go through - // each child. - let child = firstChild; - do { - // Update the returnFiber of the child to the newest fiber. - child.return = returnFiber; - // Retain the priority if there's any work left to do in the children. - if (child.pendingWorkPriority !== NoWork && - (returnFiber.pendingWorkPriority === NoWork || - returnFiber.pendingWorkPriority > child.pendingWorkPriority)) { - returnFiber.pendingWorkPriority = child.pendingWorkPriority; - } - } while (child = child.sibling); -} - -function beginWork(current : ?Fiber, workInProgress : Fiber) : ?Fiber { - // The current, flushed, state of this fiber is the alternate. - // Ideally nothing should rely on this, but relying on it here - // means that we don't need an additional field on the work in - // progress. - if (current && workInProgress.pendingProps === current.memoizedProps) { - // The most likely scenario is that the previous copy of the tree contains - // the same props as the new one. In that case, we can just copy the output - // and children from that node. - workInProgress.memoizedProps = workInProgress.pendingProps; - workInProgress.output = current.output; - const priorityLevel = workInProgress.pendingWorkPriority; - workInProgress.pendingProps = null; - workInProgress.pendingWorkPriority = NoWork; - workInProgress.stateNode = current.stateNode; - if (current.child) { - // If we bail out but still has work with the current priority in this - // subtree, we need to go find it right now. If we don't, we won't flush - // it until the next tick. - workInProgress.child = current.child; - reuseChildren(workInProgress, workInProgress.child); - if (workInProgress.pendingWorkPriority <= priorityLevel) { - // TODO: This passes the current node and reads the priority level and - // pending props from that. We want it to read our priority level and - // pending props from the work in progress. Needs restructuring. - return findNextUnitOfWorkAtPriority(workInProgress.alternate, priorityLevel); - } else { - return null; + function mountIndeterminateComponent(current, workInProgress) { + var fn = workInProgress.type; + var props = workInProgress.pendingProps; + var value = fn(props); + if (typeof value === 'object' && value && typeof value.render === 'function') { + console.log('performed work on class:', fn.name); + // Proceed under the assumption that this is a class instance + workInProgress.tag = ClassComponent; + if (workInProgress.alternate) { + workInProgress.alternate.tag = ClassComponent; } } else { - workInProgress.child = null; + console.log('performed work on fn:', fn.name); + // Proceed under the assumption that this is a functional component + workInProgress.tag = FunctionalComponent; + if (workInProgress.alternate) { + workInProgress.alternate.tag = FunctionalComponent; + } + } + reconcileChildren(current, workInProgress, value); + workInProgress.pendingWorkPriority = NoWork; + } + + function updateCoroutineComponent(current, workInProgress) { + var coroutine = (workInProgress.pendingProps : ?ReactCoroutine); + if (!coroutine) { + throw new Error('Should be resolved by now'); + } + console.log('begin coroutine', workInProgress.type.name); + reconcileChildren(current, workInProgress, coroutine.children); + workInProgress.pendingWorkPriority = NoWork; + } + + function reuseChildren(returnFiber : Fiber, firstChild : Fiber) { + // TODO: None of this should be necessary if structured better. + // The returnFiber pointer only needs to be updated when we walk into this child + // which we don't do right now. If the pending work priority indicated only + // if a child has work rather than if the node has work, then we would know + // by a single lookup on workInProgress rather than having to go through + // each child. + let child = firstChild; + do { + // Update the returnFiber of the child to the newest fiber. + child.return = returnFiber; + // Retain the priority if there's any work left to do in the children. + if (child.pendingWorkPriority !== NoWork && + (returnFiber.pendingWorkPriority === NoWork || + returnFiber.pendingWorkPriority > child.pendingWorkPriority)) { + returnFiber.pendingWorkPriority = child.pendingWorkPriority; + } + } while (child = child.sibling); + } + + function beginWork(current : ?Fiber, workInProgress : Fiber) : ?Fiber { + // The current, flushed, state of this fiber is the alternate. + // Ideally nothing should rely on this, but relying on it here + // means that we don't need an additional field on the work in + // progress. + if (current && workInProgress.pendingProps === current.memoizedProps) { + // The most likely scenario is that the previous copy of the tree contains + // the same props as the new one. In that case, we can just copy the output + // and children from that node. + workInProgress.memoizedProps = workInProgress.pendingProps; + workInProgress.output = current.output; + const priorityLevel = workInProgress.pendingWorkPriority; + workInProgress.pendingProps = null; + workInProgress.pendingWorkPriority = NoWork; + workInProgress.stateNode = current.stateNode; + if (current.child) { + // If we bail out but still has work with the current priority in this + // subtree, we need to go find it right now. If we don't, we won't flush + // it until the next tick. + workInProgress.child = current.child; + reuseChildren(workInProgress, workInProgress.child); + if (workInProgress.pendingWorkPriority <= priorityLevel) { + // TODO: This passes the current node and reads the priority level and + // pending props from that. We want it to read our priority level and + // pending props from the work in progress. Needs restructuring. + return findNextUnitOfWorkAtPriority(workInProgress.alternate, priorityLevel); + } else { + return null; + } + } else { + workInProgress.child = null; + return null; + } + } + + if (!workInProgress.hasWorkInProgress && + workInProgress.pendingProps === workInProgress.memoizedProps && + workInProgress.pendingWorkPriority === NoWork) { + // If we started this work before, and finished it, or if we're in a + // ping-pong update scenario, this version could already be what we're + // looking for. In that case, we should be able to just bail out. + workInProgress.pendingProps = null; + // TODO: We should be able to bail out if there is remaining work at a lower + // priority too. However, I don't know if that is safe or even better since + // the other tree could've potentially finished that work. return null; } + + workInProgress.hasWorkInProgress = true; + + switch (workInProgress.tag) { + case IndeterminateComponent: + mountIndeterminateComponent(current, workInProgress); + return workInProgress.child; + case FunctionalComponent: + updateFunctionalComponent(current, workInProgress); + return workInProgress.child; + case ClassComponent: + console.log('class component', workInProgress.pendingProps.type.name); + return workInProgress.child; + case HostContainer: + reconcileChildren(current, workInProgress, workInProgress.pendingProps); + // A yield component is just a placeholder, we can just run through the + // next one immediately. + workInProgress.pendingWorkPriority = NoWork; + if (workInProgress.child) { + return beginWork( + workInProgress.child.alternate, + workInProgress.child + ); + } + return null; + case HostComponent: + return updateHostComponent(current, workInProgress); + case CoroutineHandlerPhase: + // This is a restart. Reset the tag to the initial phase. + workInProgress.tag = CoroutineComponent; + // Intentionally fall through since this is now the same. + case CoroutineComponent: + updateCoroutineComponent(current, workInProgress); + // This doesn't take arbitrary time so we could synchronously just begin + // eagerly do the work of workInProgress.child as an optimization. + if (workInProgress.child) { + return beginWork( + workInProgress.child.alternate, + workInProgress.child + ); + } + return workInProgress.child; + case YieldComponent: + // A yield component is just a placeholder, we can just run through the + // next one immediately. + workInProgress.pendingWorkPriority = NoWork; + if (workInProgress.sibling) { + return beginWork( + workInProgress.sibling.alternate, + workInProgress.sibling + ); + } + return null; + default: + throw new Error('Unknown unit of work tag'); + } } - if (!workInProgress.hasWorkInProgress && - workInProgress.pendingProps === workInProgress.memoizedProps && - workInProgress.pendingWorkPriority === NoWork) { - // If we started this work before, and finished it, or if we're in a - // ping-pong update scenario, this version could already be what we're - // looking for. In that case, we should be able to just bail out. - workInProgress.pendingProps = null; - // TODO: We should be able to bail out if there is remaining work at a lower - // priority too. However, I don't know if that is safe or even better since - // the other tree could've potentially finished that work. - return null; - } + return { + beginWork, + }; - workInProgress.hasWorkInProgress = true; - - switch (workInProgress.tag) { - case IndeterminateComponent: - mountIndeterminateComponent(current, workInProgress); - return workInProgress.child; - case FunctionalComponent: - updateFunctionalComponent(current, workInProgress); - return workInProgress.child; - case ClassComponent: - console.log('class component', workInProgress.pendingProps.type.name); - return workInProgress.child; - case HostContainer: - reconcileChildren(current, workInProgress, workInProgress.pendingProps); - // A yield component is just a placeholder, we can just run through the - // next one immediately. - workInProgress.pendingWorkPriority = NoWork; - if (workInProgress.child) { - return beginWork( - workInProgress.child.alternate, - workInProgress.child - ); - } - return null; - case HostComponent: - return updateHostComponent(current, workInProgress); - case CoroutineHandlerPhase: - // This is a restart. Reset the tag to the initial phase. - workInProgress.tag = CoroutineComponent; - // Intentionally fall through since this is now the same. - case CoroutineComponent: - updateCoroutineComponent(current, workInProgress); - // This doesn't take arbitrary time so we could synchronously just begin - // eagerly do the work of workInProgress.child as an optimization. - if (workInProgress.child) { - return beginWork( - workInProgress.child.alternate, - workInProgress.child - ); - } - return workInProgress.child; - case YieldComponent: - // A yield component is just a placeholder, we can just run through the - // next one immediately. - workInProgress.pendingWorkPriority = NoWork; - if (workInProgress.sibling) { - return beginWork( - workInProgress.sibling.alternate, - workInProgress.sibling - ); - } - return null; - default: - throw new Error('Unknown unit of work tag'); - } -} - -exports.beginWork = beginWork; +}; diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js index f4cce35f0c..161c2b3c8d 100644 --- a/src/renderers/shared/fiber/ReactFiberCommitWork.js +++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js @@ -13,6 +13,7 @@ 'use strict'; import type { Fiber } from 'ReactFiber'; +import type { HostConfig } from 'ReactFiberReconciler'; var ReactTypeOfWork = require('ReactTypeOfWork'); var { @@ -21,18 +22,26 @@ var { HostComponent, } = ReactTypeOfWork; -exports.commitWork = function(finishedWork : Fiber) : void { - switch (finishedWork.tag) { - case ClassComponent: - // TODO: Fire componentDidMount/componentDidUpdate, update refs - return; - case HostContainer: - // TODO: Attach children to root container. - return; - case HostComponent: - console.log('commit updates to host component', finishedWork.type); - return; - default: - throw new Error('This unit of work tag should not have side-effects.'); +module.exports = function(config : HostConfig) { + + function commitWork(finishedWork : Fiber) : void { + switch (finishedWork.tag) { + case ClassComponent: + // TODO: Fire componentDidMount/componentDidUpdate, update refs + return; + case HostContainer: + // TODO: Attach children to root container. + return; + case HostComponent: + console.log('commit updates to host component', finishedWork.type); + return; + default: + throw new Error('This unit of work tag should not have side-effects.'); + } } + + return { + commitWork, + }; + }; diff --git a/src/renderers/shared/fiber/ReactFiberCompleteWork.js b/src/renderers/shared/fiber/ReactFiberCompleteWork.js index 53cc75533c..50c6e6895f 100644 --- a/src/renderers/shared/fiber/ReactFiberCompleteWork.js +++ b/src/renderers/shared/fiber/ReactFiberCompleteWork.js @@ -14,6 +14,7 @@ import type { ReactCoroutine } from 'ReactCoroutine'; import type { Fiber } from 'ReactFiber'; +import type { HostConfig } from 'ReactFiberReconciler'; import type { ReifiedYield } from 'ReactReifiedYield'; @@ -30,117 +31,125 @@ var { YieldComponent, } = ReactTypeOfWork; -function markForPostEffect(workInProgress : Fiber) { - // Schedule a side-effect on this fiber, after the children's side-effects. - if (workInProgress.lastEffect) { - workInProgress.lastEffect.nextEffect = workInProgress; - } else { - workInProgress.firstEffect = workInProgress; - } - workInProgress.lastEffect = workInProgress; -} +module.exports = function(config : HostConfig) { -function transferOutput(child : ?Fiber, returnFiber : Fiber) { - // If we have a single result, we just pass that through as the output to - // avoid unnecessary traversal. When we have multiple output, we just pass - // the linked list of fibers that has the individual output values. - returnFiber.output = (child && !child.sibling) ? child.output : child; - returnFiber.memoizedProps = returnFiber.pendingProps; -} - -function recursivelyFillYields(yields, output : ?Fiber | ?ReifiedYield) { - if (!output) { - // Ignore nulls etc. - } else if (output.tag !== undefined) { // TODO: Fix this fragile duck test. - // Detect if this is a fiber, if so it is a fragment result. - // $FlowFixMe: Refinement issue. - var item = (output : Fiber); - do { - recursivelyFillYields(yields, item.output); - item = item.sibling; - } while (item); - } else { - // $FlowFixMe: Refinement issue. If it is not a Fiber or null, it is a yield - yields.push(output); - } -} - -function moveCoroutineToHandlerPhase(current : ?Fiber, workInProgress : Fiber) { - var coroutine = (workInProgress.pendingProps : ?ReactCoroutine); - if (!coroutine) { - throw new Error('Should be resolved by now'); + function markForPostEffect(workInProgress : Fiber) { + // Schedule a side-effect on this fiber, after the children's side-effects. + if (workInProgress.lastEffect) { + workInProgress.lastEffect.nextEffect = workInProgress; + } else { + workInProgress.firstEffect = workInProgress; + } + workInProgress.lastEffect = workInProgress; } - // First step of the coroutine has completed. Now we need to do the second. - // TODO: It would be nice to have a multi stage coroutine represented by a - // single component, or at least tail call optimize nested ones. Currently - // that requires additional fields that we don't want to add to the fiber. - // So this requires nested handlers. - // Note: This doesn't mutate the alternate node. I don't think it needs to - // since this stage is reset for every pass. - workInProgress.tag = CoroutineHandlerPhase; - - // Build up the yields. - // TODO: Compare this to a generator or opaque helpers like Children. - var yields : Array = []; - var child = workInProgress.child; - while (child) { - recursivelyFillYields(yields, child.output); - child = child.sibling; + function transferOutput(child : ?Fiber, returnFiber : Fiber) { + // If we have a single result, we just pass that through as the output to + // avoid unnecessary traversal. When we have multiple output, we just pass + // the linked list of fibers that has the individual output values. + returnFiber.output = (child && !child.sibling) ? child.output : child; + returnFiber.memoizedProps = returnFiber.pendingProps; } - var fn = coroutine.handler; - var props = coroutine.props; - var nextChildren = fn(props, yields); - var currentFirstChild = current ? current.stateNode : null; - // Inherit the priority of the returnFiber. - const priority = workInProgress.pendingWorkPriority; - workInProgress.stateNode = ReactChildFiber.reconcileChildFibers( - workInProgress, - currentFirstChild, - nextChildren, - priority - ); - return workInProgress.stateNode; -} - -exports.completeWork = function(current : ?Fiber, workInProgress : Fiber) : ?Fiber { - switch (workInProgress.tag) { - case FunctionalComponent: - console.log('/functional component', workInProgress.type.name); - transferOutput(workInProgress.child, workInProgress); - return null; - case ClassComponent: - console.log('/class component', workInProgress.type.name); - transferOutput(workInProgress.child, workInProgress); - return null; - case HostContainer: - return null; - case HostComponent: - transferOutput(workInProgress.child, workInProgress); - if (workInProgress.alternate) { - // If we have an alternate, that means this is an update and we need to - // schedule a side-effect to do the updates. - markForPostEffect(workInProgress); - } - console.log('/host component', workInProgress.type); - return null; - case CoroutineComponent: - console.log('/coroutine component', workInProgress.pendingProps.handler.name); - return moveCoroutineToHandlerPhase(current, workInProgress); - case CoroutineHandlerPhase: - transferOutput(workInProgress.stateNode, workInProgress); - // Reset the tag to now be a first phase coroutine. - workInProgress.tag = CoroutineComponent; - return null; - case YieldComponent: - // Does nothing. - return null; - - // Error cases - case IndeterminateComponent: - throw new Error('An indeterminate component should have become determinate before completing.'); - default: - throw new Error('Unknown unit of work tag'); + function recursivelyFillYields(yields, output : ?Fiber | ?ReifiedYield) { + if (!output) { + // Ignore nulls etc. + } else if (output.tag !== undefined) { // TODO: Fix this fragile duck test. + // Detect if this is a fiber, if so it is a fragment result. + // $FlowFixMe: Refinement issue. + var item = (output : Fiber); + do { + recursivelyFillYields(yields, item.output); + item = item.sibling; + } while (item); + } else { + // $FlowFixMe: Refinement issue. If it is not a Fiber or null, it is a yield + yields.push(output); + } } + + function moveCoroutineToHandlerPhase(current : ?Fiber, workInProgress : Fiber) { + var coroutine = (workInProgress.pendingProps : ?ReactCoroutine); + if (!coroutine) { + throw new Error('Should be resolved by now'); + } + + // First step of the coroutine has completed. Now we need to do the second. + // TODO: It would be nice to have a multi stage coroutine represented by a + // single component, or at least tail call optimize nested ones. Currently + // that requires additional fields that we don't want to add to the fiber. + // So this requires nested handlers. + // Note: This doesn't mutate the alternate node. I don't think it needs to + // since this stage is reset for every pass. + workInProgress.tag = CoroutineHandlerPhase; + + // Build up the yields. + // TODO: Compare this to a generator or opaque helpers like Children. + var yields : Array = []; + var child = workInProgress.child; + while (child) { + recursivelyFillYields(yields, child.output); + child = child.sibling; + } + var fn = coroutine.handler; + var props = coroutine.props; + var nextChildren = fn(props, yields); + + var currentFirstChild = current ? current.stateNode : null; + // Inherit the priority of the returnFiber. + const priority = workInProgress.pendingWorkPriority; + workInProgress.stateNode = ReactChildFiber.reconcileChildFibers( + workInProgress, + currentFirstChild, + nextChildren, + priority + ); + return workInProgress.stateNode; + } + + function completeWork(current : ?Fiber, workInProgress : Fiber) : ?Fiber { + switch (workInProgress.tag) { + case FunctionalComponent: + console.log('/functional component', workInProgress.type.name); + transferOutput(workInProgress.child, workInProgress); + return null; + case ClassComponent: + console.log('/class component', workInProgress.type.name); + transferOutput(workInProgress.child, workInProgress); + return null; + case HostContainer: + return null; + case HostComponent: + transferOutput(workInProgress.child, workInProgress); + if (workInProgress.alternate) { + // If we have an alternate, that means this is an update and we need to + // schedule a side-effect to do the updates. + markForPostEffect(workInProgress); + } + console.log('/host component', workInProgress.type); + return null; + case CoroutineComponent: + console.log('/coroutine component', workInProgress.pendingProps.handler.name); + return moveCoroutineToHandlerPhase(current, workInProgress); + case CoroutineHandlerPhase: + transferOutput(workInProgress.stateNode, workInProgress); + // Reset the tag to now be a first phase coroutine. + workInProgress.tag = CoroutineComponent; + return null; + case YieldComponent: + // Does nothing. + return null; + + // Error cases + case IndeterminateComponent: + throw new Error('An indeterminate component should have become determinate before completing.'); + default: + throw new Error('Unknown unit of work tag'); + } + } + + return { + completeWork, + }; + }; diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index 50cf30eb5d..c3aab11536 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -16,10 +16,11 @@ import type { Fiber } from 'ReactFiber'; import type { FiberRoot } from 'ReactFiberRoot'; import type { HostConfig } from 'ReactFiberReconciler'; +var ReactFiberBeginWork = require('ReactFiberBeginWork'); +var ReactFiberCompleteWork = require('ReactFiberCompleteWork'); +var ReactFiberCommitWork = require('ReactFiberCommitWork'); + var { cloneFiber } = require('ReactFiber'); -var { beginWork } = require('ReactFiberBeginWork'); -var { completeWork } = require('ReactFiberCompleteWork'); -var { commitWork } = require('ReactFiberCommitWork'); var { findNextUnitOfWorkAtPriority } = require('ReactFiberPendingWork'); var { @@ -33,6 +34,10 @@ var timeHeuristicForUnitOfWork = 1; module.exports = function(config : HostConfig) { + const { beginWork } = ReactFiberBeginWork(config); + const { completeWork } = ReactFiberCompleteWork(config); + const { commitWork } = ReactFiberCommitWork(config); + // const scheduleHighPriCallback = config.scheduleHighPriCallback; const scheduleLowPriCallback = config.scheduleLowPriCallback;