mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Tag the fiber with the kind of side-effect that was applied to it
This allow us to track what kind of side-effect this was even though we only have a single linked list for all side-effects.
This commit is contained in:
committed by
Sebastian Markbåge
parent
e9e645a9b1
commit
901691eb92
@@ -25,6 +25,7 @@ var {
|
||||
var ReactFiber = require('ReactFiber');
|
||||
var ReactPriorityLevel = require('ReactPriorityLevel');
|
||||
var ReactReifiedYield = require('ReactReifiedYield');
|
||||
var ReactTypeOfSideEffect = require('ReactTypeOfSideEffect');
|
||||
var ReactTypeOfWork = require('ReactTypeOfWork');
|
||||
|
||||
var getIteratorFn = require('getIteratorFn');
|
||||
@@ -56,6 +57,12 @@ const {
|
||||
NoWork,
|
||||
} = ReactPriorityLevel;
|
||||
|
||||
const {
|
||||
NoEffect,
|
||||
Placement,
|
||||
Deletion,
|
||||
} = ReactTypeOfSideEffect;
|
||||
|
||||
// This wrapper function exists because I expect to clone the code in each path
|
||||
// to be able to optimize each path individually by branching early. This needs
|
||||
// a compiler or we can do it manually. Helpers that don't need this branching
|
||||
@@ -90,6 +97,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
childToDelete;
|
||||
}
|
||||
childToDelete.nextEffect = null;
|
||||
childToDelete.effectTag = Deletion;
|
||||
}
|
||||
|
||||
function deleteRemainingChildren(
|
||||
@@ -145,6 +153,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
fiber.pendingWorkPriority > priority) {
|
||||
fiber.pendingWorkPriority = priority;
|
||||
}
|
||||
fiber.effectTag = NoWork;
|
||||
fiber.index = 0;
|
||||
fiber.sibling = null;
|
||||
return fiber;
|
||||
@@ -162,7 +171,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
const oldIndex = current.index;
|
||||
if (oldIndex < lastPlacedIndex) {
|
||||
// This is a move.
|
||||
// TODO: Schedule a move side-effect for this child.
|
||||
newFiber.effectTag = Placement;
|
||||
return lastPlacedIndex;
|
||||
} else {
|
||||
// This item can stay in place.
|
||||
@@ -170,7 +179,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
}
|
||||
} else {
|
||||
// This is an insertion.
|
||||
// TODO: Schedule an insertion side-effect for this child.
|
||||
newFiber.effectTag = Placement;
|
||||
return lastPlacedIndex;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +216,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
// Move based on index, TODO: This needs to restore a deletion marking.
|
||||
// Move based on index
|
||||
const existing = useFiber(current, priority);
|
||||
existing.pendingProps = element.props;
|
||||
existing.return = returnFiber;
|
||||
@@ -228,7 +237,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
// Move based on index, TODO: This needs to restore a deletion marking.
|
||||
// Move based on index
|
||||
const existing = useFiber(current, priority);
|
||||
existing.pendingProps = coroutine;
|
||||
existing.return = returnFiber;
|
||||
@@ -251,7 +260,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
// Move based on index, TODO: This needs to restore a deletion marking.
|
||||
// Move based on index
|
||||
const existing = useFiber(current, priority);
|
||||
existing.output = createUpdatedReifiedYield(
|
||||
current.output,
|
||||
@@ -397,9 +406,6 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
priority : PriorityLevel
|
||||
) : ?Fiber {
|
||||
|
||||
// TODO: If this child matches, we need to undo the deletion. However,
|
||||
// we don't do that for the updateSlot case because nothing was deleted yet.
|
||||
|
||||
if (typeof newChild === 'string' || typeof newChild === 'number') {
|
||||
// Text nodes doesn't have keys, so we neither have to check the old nor
|
||||
// new node for the key. If both are text nodes, they match.
|
||||
@@ -571,11 +577,15 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
}
|
||||
|
||||
if (shouldTrackSideEffects) {
|
||||
// Any existing children that we're consumed above were deleted. We need
|
||||
// Any existing children that weren't consumed above were deleted. We need
|
||||
// to add them to the deletion list.
|
||||
existingChildren.forEach(child => deleteChild(returnFiber, child));
|
||||
}
|
||||
|
||||
// TODO: Add deletions and insert/moves to the side-effect list.
|
||||
// TODO: Clear the deletion list when we don't reconcile in place. When
|
||||
// progressedChild isn't reused.
|
||||
|
||||
return resultingFirstChild;
|
||||
}
|
||||
|
||||
@@ -718,10 +728,9 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
||||
return created;
|
||||
}
|
||||
|
||||
// TODO: This API will tag the children with the side-effect of the
|
||||
// reconciliation itself. Deletes have to get added to the side-effect list
|
||||
// of the return fiber right now. Other side-effects will be added as we
|
||||
// pass through those children.
|
||||
// This API will tag the children with the side-effect of the reconciliation
|
||||
// itself. They will be added to the side-effect list as we pass through the
|
||||
// children and the parent.
|
||||
function reconcileChildFibers(
|
||||
returnFiber : Fiber,
|
||||
currentFirstChild : ?Fiber,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import type { ReactFragment } from 'ReactTypes';
|
||||
import type { ReactCoroutine, ReactYield } from 'ReactCoroutine';
|
||||
import type { TypeOfWork } from 'ReactTypeOfWork';
|
||||
import type { TypeOfSideEffect } from 'ReactTypeOfSideEffect';
|
||||
import type { PriorityLevel } from 'ReactPriorityLevel';
|
||||
import type { UpdateQueue } from 'ReactFiberUpdateQueue';
|
||||
|
||||
@@ -34,6 +35,10 @@ var {
|
||||
NoWork,
|
||||
} = require('ReactPriorityLevel');
|
||||
|
||||
var {
|
||||
NoEffect,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
|
||||
// An Instance is shared between all versions of a component. We can easily
|
||||
// break this out into a separate object to avoid copying so much to the
|
||||
// alternate versions of the tree. We put this on a single object for now to
|
||||
@@ -91,6 +96,9 @@ export type Fiber = Instance & {
|
||||
// if this returns multiple values. Such as a fragment.
|
||||
output: any, // This type will be more specific once we overload the tag.
|
||||
|
||||
// Effect
|
||||
effectTag: TypeOfSideEffect,
|
||||
|
||||
// Singly linked list fast path to the next fiber with side-effects.
|
||||
nextEffect: ?Fiber,
|
||||
|
||||
@@ -175,6 +183,7 @@ var createFiber = function(tag : TypeOfWork, key : null | string) : Fiber {
|
||||
callbackList: null,
|
||||
output: null,
|
||||
|
||||
effectTag: NoEffect,
|
||||
nextEffect: null,
|
||||
firstEffect: null,
|
||||
lastEffect: null,
|
||||
@@ -214,6 +223,7 @@ exports.cloneFiber = function(fiber : Fiber, priorityLevel : PriorityLevel) : Fi
|
||||
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.
|
||||
alt.effectTag = NoEffect;
|
||||
alt.nextEffect = null;
|
||||
alt.firstEffect = null;
|
||||
alt.lastEffect = null;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule ReactTypeOfSideEffect
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type TypeOfSideEffect = 0 | 1 | 2 | 3 | 4;
|
||||
|
||||
module.exports = {
|
||||
NoEffect: 0,
|
||||
Placement: 1,
|
||||
Update: 2,
|
||||
PlacementAndUpdate: 3,
|
||||
Deletion: 4,
|
||||
};
|
||||
Reference in New Issue
Block a user