Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d9393ee
Add Fragment fiber type
sebmarkbage Sep 13, 2016
e8c1cb4
Add Text node types
sebmarkbage Sep 14, 2016
d7322d8
Silence Fiber warning when the feature flag is on
sebmarkbage Sep 13, 2016
e05ab67
Fix MultiChild tests so they work with Fiber
sebmarkbage Sep 13, 2016
8c7409b
Add comment about bug in yields
sebmarkbage Sep 15, 2016
4ed67f1
Enable text updates in ReactNoop
sebmarkbage Sep 19, 2016
dff0faf
Fiber child reconciliation
sebmarkbage Sep 20, 2016
51f2bf9
Add index field to each fiber
sebmarkbage Sep 21, 2016
bcbceae
Don't track side-effects unless needed
sebmarkbage Sep 21, 2016
c49a91c
Fast path for create child
sebmarkbage Oct 4, 2016
be0acf8
Deletion tracking
sebmarkbage Oct 4, 2016
76725fe
Tag the fiber with the kind of side-effect that was applied to it
sebmarkbage Oct 4, 2016
86e854e
Append deletions to the effect list
sebmarkbage Oct 4, 2016
eabed69
Move child updates to use the reconciled effects
sebmarkbage Oct 5, 2016
31ca1e7
Remove beginWork shortcut
sebmarkbage Oct 6, 2016
0262e70
Reset effect list when we recompute children
sebmarkbage Oct 7, 2016
f3d7116
Always override priority level when visiting children
sebmarkbage Oct 7, 2016
40989f8
Call componentWillUnmount during deletion phase
sebmarkbage Oct 7, 2016
8360088
Fire componentDidMount/componentDidUpdate life-cycles
sebmarkbage Oct 7, 2016
48cf81c
Resolve ref callbacks
sebmarkbage Oct 7, 2016
8721ec1
Invoke all null ref calls before any new ref calls
sebmarkbage Oct 7, 2016
d9efde7
Fix resuming bug
sebmarkbage Oct 10, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Reset effect list when we recompute children
We only use the effect list when we reuse our progressed children.
Otherwise it needs to reset to null.

In all other branches, other than bailoutOnLowPriority, we
revisit the children which recreates this list.

We should also not add fibers to their own effect list since it
becomes difficult to perform work on self without touching the
children too. Nothing else does that neither.

Since that means that the root isn't added to an effect list we
need to special case the root.
  • Loading branch information
sebmarkbage committed Oct 17, 2016
commit 0262e70ae2d20d49f5baff5d356af8f4d4af8b98
5 changes: 3 additions & 2 deletions src/renderers/shared/fiber/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,9 @@ exports.cloneFiber = function(fiber : Fiber, priorityLevel : PriorityLevel) : Fi
// extra memory if needed.
let alt = fiber.alternate;
if (alt) {
// Whenever we clone, we do so to get a new work in progress.
// This ensures that we've reset these in the new tree.
// If we clone, then we do so from the "current" state. The current state
// can't have any side-effects that are still valid so we reset just to be
// sure.
alt.effectTag = NoEffect;
alt.nextEffect = null;
alt.firstEffect = null;
Expand Down
11 changes: 11 additions & 0 deletions src/renderers/shared/fiber/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,15 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>, g

function bailoutOnLowPriority(current, workInProgress) {
if (current) {
// TODO: If I have started work on this node, mark it as finished, then
// return do other work, come back and hit this node... we killed that
// work. It is now in an inconsistent state. We probably need to check
// progressedChild or something.
workInProgress.child = current.child;
workInProgress.memoizedProps = current.memoizedProps;
workInProgress.output = current.output;
workInProgress.firstEffect = null;
workInProgress.lastEffect = null;
}
return null;
}
Expand All @@ -416,6 +422,11 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>, g
return bailoutOnLowPriority(current, workInProgress);
}

// If we don't bail out, we're going be recomputing our children so we need
// to drop our effect list.
workInProgress.firstEffect = null;
workInProgress.lastEffect = null;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct. This breaks the demo. Need to think about this some more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction. This is correct but I believe the problem is the TODO comment above in bailoutOnLowPriority. Needs to be fixed.


if (workInProgress.progressedPriority === priorityLevel) {
// If we have progressed work on this priority level already, we can
// proceed this that as the child.
Expand Down
36 changes: 22 additions & 14 deletions src/renderers/shared/fiber/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
effectfulFiber.nextEffect = null;
effectfulFiber = next;
}

// Finally if the root itself had an effect, we perform that since it is not
// part of the effect list.
if (finishedWork.effectTag !== NoEffect) {
const current = finishedWork.alternate;
commitWork(current, finishedWork);
}
}

function resetWorkPriority(workInProgress : Fiber) {
Expand Down Expand Up @@ -179,20 +186,6 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
workInProgress.pendingProps = null;
workInProgress.updateQueue = null;

// If this fiber had side-effects, we append it to the end of its own
// effect list.
if (workInProgress.effectTag !== NoEffect) {
// Schedule a side-effect on this fiber, AFTER the children's
// side-effects. We can perform certain side-effects earlier if
// needed, by doing multiple passes over the effect list.
if (workInProgress.lastEffect) {
workInProgress.lastEffect.nextEffect = workInProgress;
} else {
workInProgress.firstEffect = workInProgress;
}
workInProgress.lastEffect = workInProgress;
}

const returnFiber = workInProgress.return;

if (returnFiber) {
Expand All @@ -208,6 +201,21 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
}
returnFiber.lastEffect = workInProgress.lastEffect;
}

// If this fiber had side-effects, we append it AFTER the children's
// side-effects. We can perform certain side-effects earlier if
// needed, by doing multiple passes over the effect list. We don't want
// to schedule our own side-effect on our own list because if end up
// reusing children we'll schedule this effect onto itself since we're
// at the end.
if (workInProgress.effectTag !== NoEffect) {
if (returnFiber.lastEffect) {
returnFiber.lastEffect.nextEffect = workInProgress;
} else {
returnFiber.firstEffect = workInProgress;
}
returnFiber.lastEffect = workInProgress;
}
}

if (next) {
Expand Down