diff --git a/scripts/fiber/tests-failing.txt b/scripts/fiber/tests-failing.txt index 75e3b3f0c9840..46e114bb2454e 100644 --- a/scripts/fiber/tests-failing.txt +++ b/scripts/fiber/tests-failing.txt @@ -59,9 +59,6 @@ src/renderers/shared/hooks/__tests__/ReactHostOperationHistoryHook-test.js src/renderers/shared/shared/__tests__/ReactComponentLifeCycle-test.js * should carry through each of the phases of setup -src/renderers/shared/shared/__tests__/ReactCompositeComponent-test.js -* should update refs if shouldComponentUpdate gives false - src/renderers/shared/shared/__tests__/ReactEmptyComponent-test.js * should still throw when rendering to undefined diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index 922e9985011a8..b8d1a4991de46 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -1380,6 +1380,7 @@ src/renderers/shared/shared/__tests__/ReactCompositeComponent-test.js * should trigger componentWillReceiveProps for context changes * only renders once if updated in componentWillReceiveProps * only renders once if updated in componentWillReceiveProps when batching +* should update refs if shouldComponentUpdate gives false * should allow access to findDOMNode in componentWillUnmount * context should be passed down from the parent * should replace state diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index e5ee7a831d18a..128be59141b2b 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -58,6 +58,7 @@ var { Placement, ContentReset, Err, + Ref, } = require('ReactTypeOfSideEffect'); var ReactCurrentOwner = require('ReactCurrentOwner'); var ReactFiberClassComponent = require('ReactFiberClassComponent'); @@ -180,6 +181,14 @@ module.exports = function( return workInProgress.child; } + function markRef(current : ?Fiber, workInProgress : Fiber) { + const ref = workInProgress.ref; + if (ref && (!current || current.ref !== ref)) { + // Schedule a Ref effect + workInProgress.effectTag |= Ref; + } + } + function updateFunctionalComponent(current, workInProgress) { var fn = workInProgress.type; var nextProps = workInProgress.pendingProps; @@ -245,6 +254,10 @@ module.exports = function( hasContext : boolean, ) { // Schedule side-effects + + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + if (shouldUpdate) { workInProgress.effectTag |= Update; } else { @@ -364,6 +377,9 @@ module.exports = function( // empty, we need to schedule the text content to be reset. workInProgress.effectTag |= ContentReset; } + + markRef(current, workInProgress); + if (nextProps.hidden && workInProgress.pendingWorkPriority !== OffscreenPriority) { // If this host component is hidden, we can bail out on the children. diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js index 429e892e0bef5..382046ff24e47 100644 --- a/src/renderers/shared/fiber/ReactFiberCommitWork.js +++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js @@ -84,13 +84,6 @@ module.exports = function( } } - function attachRef(current : ?Fiber, finishedWork : Fiber, instance : any) { - const ref = finishedWork.ref; - if (ref && (!current || current.ref !== ref)) { - ref(instance); - } - } - function getHostParent(fiber : Fiber) : I | C { let parent = fiber.return; while (parent) { @@ -416,7 +409,6 @@ module.exports = function( instance.componentDidUpdate(prevProps, prevState); } } - attachRef(current, finishedWork, instance); } const callbackList = finishedWork.callbackList; if (callbackList) { @@ -434,7 +426,6 @@ module.exports = function( } case HostComponent: { const instance : I = finishedWork.stateNode; - attachRef(current, finishedWork, instance); // Renderers may schedule work to be done after host components are mounted // (eg DOM renderer may schedule auto-focus for inputs and form controls). @@ -465,11 +456,23 @@ module.exports = function( } } + function commitRef(finishedWork : Fiber) { + if (finishedWork.tag !== ClassComponent && finishedWork.tag !== HostComponent) { + return; + } + const ref = finishedWork.ref; + if (ref) { + const instance = finishedWork.stateNode; + ref(instance); + } + } + return { commitPlacement, commitDeletion, commitWork, commitLifeCycles, + commitRef, }; }; diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index 9dc0661b103aa..435e3e6483ca0 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -49,6 +49,7 @@ var { ContentReset, Callback, Err, + Ref, } = require('ReactTypeOfSideEffect'); var { @@ -88,6 +89,7 @@ module.exports = function(config : HostConfig(config : HostConfig(config : HostConfig