@samitouri / QOS-React / commits / a481016883

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;