Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fiber] Update refs even if shouldComponentUpdate returns false #8685

Merged
merged 1 commit into from
Jan 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions scripts/fiber/tests-failing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions scripts/fiber/tests-passing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/renderers/shared/fiber/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var {
Placement,
ContentReset,
Err,
Ref,
} = require('ReactTypeOfSideEffect');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactFiberClassComponent = require('ReactFiberClassComponent');
Expand Down Expand Up @@ -180,6 +181,14 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
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;
Expand Down Expand Up @@ -245,6 +254,10 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
hasContext : boolean,
) {
// Schedule side-effects

// Refs should update even if shouldComponentUpdate returns false
markRef(current, workInProgress);

if (shouldUpdate) {
workInProgress.effectTag |= Update;
} else {
Expand Down Expand Up @@ -364,6 +377,9 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
// 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.
Expand Down
21 changes: 12 additions & 9 deletions src/renderers/shared/fiber/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,6 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
}
}

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) {
Expand Down Expand Up @@ -416,7 +409,6 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
instance.componentDidUpdate(prevProps, prevState);
}
}
attachRef(current, finishedWork, instance);
}
const callbackList = finishedWork.callbackList;
if (callbackList) {
Expand All @@ -434,7 +426,6 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
}
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).
Expand Down Expand Up @@ -465,11 +456,23 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
}
}

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,
};

};
8 changes: 7 additions & 1 deletion src/renderers/shared/fiber/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var {
ContentReset,
Callback,
Err,
Ref,
} = require('ReactTypeOfSideEffect');

var {
Expand Down Expand Up @@ -88,6 +89,7 @@ module.exports = function<T, P, I, TI, C, CX, CI>(config : HostConfig<T, P, I, T
commitDeletion,
commitWork,
commitLifeCycles,
commitRef,
} = ReactFiberCommitWork(config, hostContext, captureError);
const {
scheduleAnimationCallback: hostScheduleAnimationCallback,
Expand Down Expand Up @@ -241,7 +243,7 @@ module.exports = function<T, P, I, TI, C, CX, CI>(config : HostConfig<T, P, I, T
// possible bitmap value, we remove the secondary effects from the
// effect tag and switch on that value.
let primaryEffectTag =
nextEffect.effectTag & ~(Callback | Err | ContentReset);
nextEffect.effectTag & ~(Callback | Err | ContentReset | Ref);
switch (primaryEffectTag) {
case Placement: {
commitPlacement(nextEffect);
Expand Down Expand Up @@ -293,6 +295,10 @@ module.exports = function<T, P, I, TI, C, CX, CI>(config : HostConfig<T, P, I, T
commitLifeCycles(current, nextEffect);
}

if (nextEffect.effectTag & Ref) {
commitRef(nextEffect);
}

if (nextEffect.effectTag & Err) {
commitErrorHandling(nextEffect);
}
Expand Down
19 changes: 10 additions & 9 deletions src/renderers/shared/fiber/ReactTypeOfSideEffect.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@

'use strict';

export type TypeOfSideEffect = 0 | 1 | 2 | 3 | 4 | 8 | 16 | 32;
export type TypeOfSideEffect = 0 | 1 | 2 | 3 | 4 | 8 | 16 | 32 | 64;

module.exports = {
NoEffect: 0, // 0b000000
Placement: 1, // 0b000001
Update: 2, // 0b000010
PlacementAndUpdate: 3, // 0b000011
Deletion: 4, // 0b000100
ContentReset: 8, // 0b001000
Callback: 16, // 0b010000
Err: 32, // 0b100000
NoEffect: 0, // 0b0000000
Placement: 1, // 0b0000001
Update: 2, // 0b0000010
PlacementAndUpdate: 3, // 0b0000011
Deletion: 4, // 0b0000100
ContentReset: 8, // 0b0001000
Callback: 16, // 0b0010000
Err: 32, // 0b0100000
Ref: 64, // 0b1000000
};