Preserve the original object when using replaceState
When we use only replace state we don't need to clone the object.
Sebastian Markbage committed
Nov 20, 2016 at 21:28 UTC
a48101688386855be96052176dbadb18583ea348
3 files changed
+21
-10
scripts/fiber/tests-failing.txt
-1
@@ -114,7 +114,6 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
114
* should warn about `setState` in render
115
* should warn about `setState` in getChildContext
116
* should update refs if shouldComponentUpdate gives false
117
-* should support objects with prototypes as state
117
118
src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponentNestedState-test.js
119
* should provide up to date values for props
scripts/fiber/tests-passing.txt
+1
@@ -1284,6 +1284,7 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
1284
* should allow access to findDOMNode in componentWillUnmount
1285
* context should be passed down from the parent
1286
* should replace state
1287
+* should support objects with prototypes as state
1288
* should not warn about unmounting during unmounting
1289
* should only call componentWillUnmount once
1290
src/renderers/shared/fiber/ReactFiberUpdateQueue.js
+20
-9
@@ -87,19 +87,30 @@ exports.callCallbacks = function(queue : UpdateQueue, context : any) : Error | n
87
return firstError;
88
};
89
90
+function getStateFromNode(node, instance, state, props) {
91
+ if (typeof node.partialState === 'function') {
92
+ const updateFn = node.partialState;
93
+ return updateFn.call(instance, state, props);
94
+ } else {
95
+ return node.partialState;
96
+ }
97
+}
98
+
99
exports.mergeUpdateQueue = function(queue : UpdateQueue, instance : any, prevState : any, props : any) : any {
100
let node : ?UpdateQueueNode = queue;
101
+ if (queue.isReplace) {
102
+ // replaceState is always first in the queue.
103
+ prevState = getStateFromNode(queue, instance, prevState, props);
104
+ node = queue.next;
105
+ if (!node) {
106
+ // If there is no more work, we replace the raw object instead of cloning.
107
+ return prevState;
108
+ }
109
+ }
110
let state = Object.assign({}, prevState);
111
while (node) {
94
- state = node.isReplace ? null : state;
95
- let partialState;
96
- if (typeof node.partialState === 'function') {
97
- const updateFn = node.partialState;
98
- partialState = updateFn.call(instance, state, props);
99
- } else {
100
- partialState = node.partialState;
101
- }
102
- state = Object.assign(state || {}, partialState);
112
+ let partialState = getStateFromNode(node, instance, state, props);
113
+ Object.assign(state, partialState);
114
node = node.next;
115
}
116
return state;