From aaacbe96f056e1258d22267cc0a4de1168866611 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 9 Dec 2019 11:32:11 -0800 Subject: [PATCH] Add regression test for update queue bug This test passes in the old legacy update queue implementation. I'm adding this before the refactor to prevent a regression. --- .../ReactIncrementalUpdates-test.internal.js | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js index 095f3d8979a6a..832e1a55f4259 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js @@ -717,4 +717,52 @@ describe('ReactIncrementalUpdates', () => { ]); expect(root).toMatchRenderedOutput('ABCD'); }); + + it("base state of update queue is initialized to its fiber's memoized state", async () => { + // This test is very weird because it tests an implementation detail but + // is tested in terms of public APIs. When it was originally written, the + // test failed because the update queue was initialized to the state of + // the alternate fiber. + let app; + class App extends React.Component { + state = {prevProp: 'A', count: 0}; + static getDerivedStateFromProps(props, state) { + // Add 100 whenever the label prop changes. The prev label is stored + // in state. If the state is dropped incorrectly, we'll fail to detect + // prop changes. + if (props.prop !== state.prevProp) { + return { + prevProp: props.prop, + count: state.count + 100, + }; + } + return null; + } + render() { + app = this; + return this.state.count; + } + } + + const root = ReactNoop.createRoot(); + await ReactNoop.act(async () => { + root.render(); + }); + expect(root).toMatchRenderedOutput('0'); + + // Changing the prop causes the count to increase by 100 + await ReactNoop.act(async () => { + root.render(); + }); + expect(root).toMatchRenderedOutput('100'); + + // Now increment the count by 1 with a state update. And, in the same + // batch, change the prop back to its original value. + await ReactNoop.act(async () => { + root.render(); + app.setState(state => ({count: state.count + 1})); + }); + // There were two total prop changes, plus an increment. + expect(root).toMatchRenderedOutput('201'); + }); });