diff --git a/packages/react-reconciler/src/ReactChildFiber.js b/packages/react-reconciler/src/ReactChildFiber.js index 8c736de5fd857..bb48f1efc1976 100644 --- a/packages/react-reconciler/src/ReactChildFiber.js +++ b/packages/react-reconciler/src/ReactChildFiber.js @@ -301,11 +301,15 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber: Fiber, expirationTime: ExpirationTime): Fiber { + function useFiber( + fiber: Fiber, + pendingProps: mixed, + expirationTime: ExpirationTime, + ): Fiber { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. if (shouldClone) { - const clone = createWorkInProgress(fiber, expirationTime); + const clone = createWorkInProgress(fiber, pendingProps, expirationTime); clone.index = 0; clone.sibling = null; return clone; @@ -317,6 +321,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { fiber.effectTag = NoEffect; fiber.index = 0; fiber.sibling = null; + fiber.pendingProps = pendingProps; return fiber; } } @@ -375,8 +380,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return created; } else { // Update - const existing = useFiber(current, expirationTime); - existing.pendingProps = textContent; + const existing = useFiber(current, textContent, expirationTime); existing.return = returnFiber; return existing; } @@ -390,9 +394,8 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { ): Fiber { if (current !== null && current.type === element.type) { // Move based on index - const existing = useFiber(current, expirationTime); + const existing = useFiber(current, element.props, expirationTime); existing.ref = coerceRef(current, element); - existing.pendingProps = element.props; existing.return = returnFiber; if (__DEV__) { existing._debugSource = element._source; @@ -430,8 +433,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return created; } else { // Move based on index - const existing = useFiber(current, expirationTime); - existing.pendingProps = call; + const existing = useFiber(current, call, expirationTime); existing.return = returnFiber; return existing; } @@ -455,7 +457,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return created; } else { // Move based on index - const existing = useFiber(current, expirationTime); + const existing = useFiber(current, null, expirationTime); existing.type = returnNode.value; existing.return = returnFiber; return existing; @@ -484,8 +486,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return created; } else { // Update - const existing = useFiber(current, expirationTime); - existing.pendingProps = portal.children || []; + const existing = useFiber(current, portal.children || [], expirationTime); existing.return = returnFiber; return existing; } @@ -510,8 +511,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { return created; } else { // Update - const existing = useFiber(current, expirationTime); - existing.pendingProps = fragment; + const existing = useFiber(current, fragment, expirationTime); existing.return = returnFiber; return existing; } @@ -1225,8 +1225,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); - const existing = useFiber(currentFirstChild, expirationTime); - existing.pendingProps = textContent; + const existing = useFiber(currentFirstChild, textContent, expirationTime); existing.return = returnFiber; return existing; } @@ -1260,11 +1259,14 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { : child.type === element.type ) { deleteRemainingChildren(returnFiber, child.sibling); - const existing = useFiber(child, expirationTime); + const existing = useFiber( + child, + element.type === REACT_FRAGMENT_TYPE + ? element.props.children + : element.props, + expirationTime, + ); existing.ref = coerceRef(child, element); - existing.pendingProps = element.type === REACT_FRAGMENT_TYPE - ? element.props.children - : element.props; existing.return = returnFiber; if (__DEV__) { existing._debugSource = element._source; @@ -1316,8 +1318,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { if (child.key === key) { if (child.tag === CallComponent) { deleteRemainingChildren(returnFiber, child.sibling); - const existing = useFiber(child, expirationTime); - existing.pendingProps = call; + const existing = useFiber(child, call, expirationTime); existing.return = returnFiber; return existing; } else { @@ -1350,7 +1351,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { if (child !== null) { if (child.tag === ReturnComponent) { deleteRemainingChildren(returnFiber, child.sibling); - const existing = useFiber(child, expirationTime); + const existing = useFiber(child, null, expirationTime); existing.type = returnNode.value; existing.return = returnFiber; return existing; @@ -1387,8 +1388,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - const existing = useFiber(child, expirationTime); - existing.pendingProps = portal.children || []; + const existing = useFiber( + child, + portal.children || [], + expirationTime, + ); existing.return = returnFiber; return existing; } else { @@ -1578,10 +1582,9 @@ exports.cloneChildFibers = function( let currentChild = workInProgress.child; let newChild = createWorkInProgress( currentChild, + currentChild.pendingProps, currentChild.expirationTime, ); - // TODO: Pass this as an argument, since it's easy to forget. - newChild.pendingProps = currentChild.pendingProps; workInProgress.child = newChild; newChild.return = workInProgress; @@ -1589,9 +1592,9 @@ exports.cloneChildFibers = function( currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, + currentChild.pendingProps, currentChild.expirationTime, ); - newChild.pendingProps = currentChild.pendingProps; newChild.return = workInProgress; } newChild.sibling = null; diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 079c50708e99f..7182dff7091a8 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow */ 'use strict'; @@ -231,6 +230,7 @@ function shouldConstruct(Component) { // This is used to create an alternate fiber to do work on. exports.createWorkInProgress = function( current: Fiber, + pendingProps: any, expirationTime: ExpirationTime, ): Fiber { let workInProgress = current.alternate; @@ -269,15 +269,13 @@ exports.createWorkInProgress = function( } workInProgress.expirationTime = expirationTime; + workInProgress.pendingProps = pendingProps; workInProgress.child = current.child; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - // pendingProps is set by the parent during reconciliation. - // TODO: Pass this as an argument. - // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; workInProgress.index = current.index; diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index da3ed2bc8c002..33d6da1e963f2 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -804,7 +804,11 @@ module.exports = function( resetContextStack(); nextRoot = root; nextRenderExpirationTime = expirationTime; - nextUnitOfWork = createWorkInProgress(nextRoot.current, expirationTime); + nextUnitOfWork = createWorkInProgress( + nextRoot.current, + null, + expirationTime, + ); } let didError = false;