Skip to content

Commit

Permalink
Updates should use the same priority context as top-level render
Browse files Browse the repository at this point in the history
A bit of restructuring so that setState uses whatever the current
priority context is, like top-level render already does.

Renamed defaultPriority to priorityContext, and added a new variable
called defaultPriorityContext. Having two separate variables allows the
default to be changed without interfering with the current context.
  • Loading branch information
acdlite committed Oct 28, 2016
1 parent 2b6f144 commit e4a160b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/renderers/shared/fiber/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var ReactFiberClassComponent = require('ReactFiberClassComponent');

module.exports = function<T, P, I, TI, C>(
config : HostConfig<T, P, I, TI, C>,
scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void
scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void
) {

const {
Expand Down
13 changes: 6 additions & 7 deletions src/renderers/shared/fiber/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type { Fiber } from 'ReactFiber';
import type { PriorityLevel } from 'ReactPriorityLevel';
import type { UpdateQueue } from 'ReactFiberUpdateQueue';

var { LowPriority } = require('ReactPriorityLevel');
var {
createUpdateQueue,
addToQueue,
Expand All @@ -27,16 +26,16 @@ var { isMounted } = require('ReactFiberTreeReflection');
var ReactInstanceMap = require('ReactInstanceMap');
var shallowEqual = require('shallowEqual');

module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void) {
module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void) {

function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue, priorityLevel : PriorityLevel) {
function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue) {
fiber.updateQueue = updateQueue;
// Schedule update on the alternate as well, since we don't know which tree
// is current.
if (fiber.alternate) {
fiber.alternate.updateQueue = updateQueue;
}
scheduleUpdate(fiber, priorityLevel);
scheduleUpdate(fiber);
}

// Class component state updater
Expand All @@ -47,19 +46,19 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
const updateQueue = fiber.updateQueue ?
addToQueue(fiber.updateQueue, partialState) :
createUpdateQueue(partialState);
scheduleUpdateQueue(fiber, updateQueue, LowPriority);
scheduleUpdateQueue(fiber, updateQueue);
},
enqueueReplaceState(instance, state) {
const fiber = ReactInstanceMap.get(instance);
const updateQueue = createUpdateQueue(state);
updateQueue.isReplace = true;
scheduleUpdateQueue(fiber, updateQueue, LowPriority);
scheduleUpdateQueue(fiber, updateQueue);
},
enqueueForceUpdate(instance) {
const fiber = ReactInstanceMap.get(instance);
const updateQueue = fiber.updateQueue || createUpdateQueue(null);
updateQueue.isForced = true;
scheduleUpdateQueue(fiber, updateQueue, LowPriority);
scheduleUpdateQueue(fiber, updateQueue);
},
enqueueCallback(instance, callback) {
const fiber = ReactInstanceMap.get(instance);
Expand Down
52 changes: 38 additions & 14 deletions src/renderers/shared/fiber/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
const scheduleAnimationCallback = config.scheduleAnimationCallback;
const scheduleDeferredCallback = config.scheduleDeferredCallback;

// The default priority to use for updates.
let defaultPriority : PriorityLevel = LowPriority;
// The priority level to use when scheduling an update.
let priorityContext : (PriorityLevel | null) = null;
// The priority level to use if there is no priority context.
let defaultPriorityContext : PriorityLevel = LowPriority;

// The next work in progress fiber that we're currently working on.
let nextUnitOfWork : ?Fiber = null;
Expand Down Expand Up @@ -450,7 +452,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
while (nextUnitOfWork &&
nextPriorityLevel === SynchronousPriority) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork, false);
// If there's no nextUnitForWork, we don't need to search for more
// If there's no nextUnitOfWork, we don't need to search for more
// because it shouldn't be possible to schedule sync work without
// immediately performing it
}
Expand Down Expand Up @@ -537,23 +539,45 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
}
}

function scheduleWork(root : FiberRoot) {
if (defaultPriority === SynchronousPriority) {
function scheduleWork(root : FiberRoot, priorityLevel : ?PriorityLevel) {
if (priorityLevel == null) {
priorityLevel = priorityContext !== null ?
priorityContext :
defaultPriorityContext;
}

if (priorityLevel === SynchronousPriority) {
root.current.pendingWorkPriority = SynchronousPriority;
performSynchronousWork();
}

if (defaultPriority === NoWork) {
if (priorityLevel === NoWork) {
return;
}
if (defaultPriority > AnimationPriority) {
scheduleDeferredWork(root, defaultPriority);
if (priorityLevel > AnimationPriority) {
scheduleDeferredWork(root, priorityLevel);
return;
}
scheduleAnimationWork(root, defaultPriority);
scheduleAnimationWork(root, priorityLevel);
}

function scheduleUpdate(fiber: Fiber, priorityLevel : PriorityLevel): void {
function scheduleUpdate(fiber: Fiber, priorityLevel : ?PriorityLevel): void {
// Use priority context if no priority is provided
if (priorityLevel == null) {
priorityLevel = priorityContext !== null ?
priorityContext :
defaultPriorityContext;
}

// Don't bother bubbling the priority to the root if it is synchronous. Just
// perform it now.
if (priorityLevel === SynchronousPriority) {
fiber.pendingWorkPriority = SynchronousPriority;
nextUnitOfWork = fiber;
performSynchronousWork();
return;
}

while (true) {
if (fiber.pendingWorkPriority === NoWork ||
fiber.pendingWorkPriority >= priorityLevel) {
Expand All @@ -568,7 +592,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
if (!fiber.return) {
if (fiber.tag === HostContainer) {
const root : FiberRoot = (fiber.stateNode : any);
scheduleDeferredWork(root, priorityLevel);
scheduleWork(root, priorityLevel);
return;
} else {
throw new Error('Invalid root');
Expand All @@ -579,12 +603,12 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
}

function performWithPriority(priorityLevel : PriorityLevel, fn : Function) {
const previousDefaultPriority = defaultPriority;
defaultPriority = priorityLevel;
const previousPriorityContext = priorityContext;
priorityContext = priorityLevel;
try {
fn();
} finally {
defaultPriority = previousDefaultPriority;
priorityContext = previousPriorityContext;
}
}

Expand Down

0 comments on commit e4a160b

Please sign in to comment.