replaceState
Adds a field to UpdateQueue that indicates whether an update should replace the previous state completely.
Andrew Clark committed
Aug 4, 2016 at 18:55 UTC
d8c24cfa78bd00691bf20dc1ad2750de84dd8ad4
3 files changed
+39
-2
src/renderers/shared/fiber/ReactFiberBeginWork.js
+6
@@ -157,6 +157,12 @@ module.exports = function<T, P, I, C>(config : HostConfig<T, P, I, C>, getSchedu
157
createUpdateQueue(partialState);
158
scheduleUpdate(fiber, updateQueue, LowPriority);
159
},
160
+ enqueueReplaceState(instance, state) {
161
+ const fiber = ReactInstanceMap.get(instance);
162
+ const updateQueue = createUpdateQueue(state);
163
+ updateQueue.isReplace = true;
164
+ scheduleUpdate(fiber, updateQueue, LowPriority);
165
+ },
166
enqueueCallback(instance, callback) {
167
const fiber = ReactInstanceMap.get(instance);
168
let updateQueue = fiber.updateQueue ?
src/renderers/shared/fiber/ReactFiberUpdateQueue.js
+4
-2
@@ -20,6 +20,7 @@ type UpdateQueueNode = {
20
};
21
22
export type UpdateQueue = UpdateQueueNode & {
23
+ isReplace: boolean,
24
tail: UpdateQueueNode
25
};
26
@@ -29,6 +30,7 @@ exports.createUpdateQueue = function(partialState : mixed) : UpdateQueue {
30
callback: null,
31
callbackWasCalled: false,
32
next: null,
33
+ isReplace: false,
34
tail: (null : any),
35
};
36
queue.tail = queue;
@@ -69,7 +71,7 @@ exports.callCallbacks = function(queue : UpdateQueue, context : any) {
71
72
exports.mergeUpdateQueue = function(queue : UpdateQueue, prevState : any, props : any) : any {
73
let node : ?UpdateQueueNode = queue;
72
- let state = Object.assign({}, prevState);
74
+ let state = queue.isReplace ? null : Object.assign({}, prevState);
75
while (node) {
76
let partialState;
77
if (typeof node.partialState === 'function') {
@@ -78,7 +80,7 @@ exports.mergeUpdateQueue = function(queue : UpdateQueue, prevState : any, props
80
} else {
81
partialState = node.partialState;
82
}
81
- state = Object.assign(state, partialState);
83
+ state = Object.assign(state || {}, partialState);
84
node = node.next;
85
}
86
return state;
src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
+29
@@ -653,4 +653,33 @@ describe('ReactIncremental', () => {
653
ReactNoop.flush();
654
expect(instance.state.num).toEqual(6);
655
});
656
+
657
+ it('can replaceState', () => {
658
+ let instance;
659
+ const Bar = React.createClass({
660
+ getInitialState() {
661
+ instance = this;
662
+ return { a: 'a' };
663
+ },
664
+ render() {
665
+ return <div>{this.props.children}</div>;
666
+ },
667
+ });
668
+
669
+ function Foo() {
670
+ return (
671
+ <div>
672
+ <Bar />
673
+ </div>
674
+ );
675
+ }
676
+
677
+ ReactNoop.render(<Foo />);
678
+ ReactNoop.flush();
679
+ instance.setState({ b: 'b' });
680
+ instance.setState({ c: 'c' });
681
+ instance.replaceState({ d: 'd' });
682
+ ReactNoop.flush();
683
+ expect(instance.state).toEqual({ d: 'd' });
684
+ });
685
});