Should not re-render as the result of a null state update (Stack)
Stack now passes test added in previous commit.
Andrew Clark committed
Dec 30, 2016 at 00:14 UTC
2af6d7a70292db15da8f2c678fe77214be8a189d
2 files changed
+31
-27
src/renderers/shared/shared/__tests__/ReactUpdates-test.js
+16
-19
@@ -1165,25 +1165,22 @@ describe('ReactUpdates', () => {
1165
expect(called).toEqual(true);
1166
});
1167
1168
- if (ReactDOMFeatureFlags.useFiber) {
1169
- // TODO: Should we add this feature to stack, too?
1170
- it('does not re-render if state update is null', () => {
1171
- let container = document.createElement('div');
1172
-
1173
- let instance;
1174
- let ops = [];
1175
- class Foo extends React.Component {
1176
- render() {
1177
- instance = this;
1178
- ops.push('render');
1179
- return <div />;
1180
- }
1168
+ it('does not re-render if state update is null', () => {
1169
+ let container = document.createElement('div');
1170
+
1171
+ let instance;
1172
+ let ops = [];
1173
+ class Foo extends React.Component {
1174
+ render() {
1175
+ instance = this;
1176
+ ops.push('render');
1177
+ return <div />;
1178
}
1182
- ReactDOM.render(<Foo />, container);
1179
+ }
1180
+ ReactDOM.render(<Foo />, container);
1181
1184
- ops = [];
1185
- instance.setState(() => null);
1186
- expect(ops).toEqual([]);
1187
- });
1188
- }
1182
+ ops = [];
1183
+ instance.setState(() => null);
1184
+ expect(ops).toEqual([]);
1185
+ });
1186
});
src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
+15
-8
@@ -867,8 +867,9 @@ var ReactCompositeComponent = {
867
868
var nextState = this._processPendingState(nextProps, nextContext);
869
var shouldUpdate = true;
870
-
870
if (!this._pendingForceUpdate) {
871
+ var prevState = inst.state;
872
+ shouldUpdate = willReceive || nextState !== prevState;
873
if (inst.shouldComponentUpdate) {
874
if (__DEV__) {
875
shouldUpdate = measureLifeCyclePerf(
@@ -944,15 +945,21 @@ var ReactCompositeComponent = {
945
return queue[0];
946
}
947
947
- var nextState = Object.assign({}, replace ? queue[0] : inst.state);
948
+ var nextState = replace ? queue[0] : inst.state;
949
+ var dontMutate = true;
950
for (var i = replace ? 1 : 0; i < queue.length; i++) {
951
var partial = queue[i];
950
- Object.assign(
951
- nextState,
952
- typeof partial === 'function' ?
953
- partial.call(inst, nextState, props, context) :
954
- partial
955
- );
952
+ let partialState = typeof partial === 'function' ?
953
+ partial.call(inst, nextState, props, context) :
954
+ partial;
955
+ if (partialState) {
956
+ if (dontMutate) {
957
+ dontMutate = false;
958
+ nextState = Object.assign({}, nextState, partialState);
959
+ } else {
960
+ Object.assign(nextState, partialState);
961
+ }
962
+ }
963
}
964
965
return nextState;