From 2a62277009beb24ed3183c0737e2f8b93fd6def9 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 14 Feb 2019 15:21:09 +0000 Subject: [PATCH] Add test cases for setState(fn) + render phase updates --- .../src/__tests__/ReactHooks-test.internal.js | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js index f7ab26011b64e..2e11f01d5a2d6 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js @@ -669,6 +669,76 @@ describe('ReactHooks', () => { }).toThrow('is not a function'); }); + it('does not forget render phase useState updates inside an effect', () => { + const {useState, useEffect} = React; + + function Counter() { + const [counter, setCounter] = useState(0); + if (counter === 0) { + setCounter(x => x + 1); + setCounter(x => x + 1); + } + useEffect(() => { + setCounter(x => x + 1); + setCounter(x => x + 1); + }, []); + return counter; + } + + const root = ReactTestRenderer.create(null); + ReactTestRenderer.act(() => { + root.update(); + }); + expect(root).toMatchRenderedOutput('4'); + }); + + it('does not forget render phase useReducer updates inside an effect with hoisted reducer', () => { + const {useReducer, useEffect} = React; + + const reducer = x => x + 1; + function Counter() { + const [counter, increment] = useReducer(reducer, 0); + if (counter === 0) { + increment(); + increment(); + } + useEffect(() => { + increment(); + increment(); + }, []); + return counter; + } + + const root = ReactTestRenderer.create(null); + ReactTestRenderer.act(() => { + root.update(); + }); + expect(root).toMatchRenderedOutput('4'); + }); + + it('does not forget render phase useReducer updates inside an effect with inline reducer', () => { + const {useReducer, useEffect} = React; + + function Counter() { + const [counter, increment] = useReducer(x => x + 1, 0); + if (counter === 0) { + increment(); + increment(); + } + useEffect(() => { + increment(); + increment(); + }, []); + return counter; + } + + const root = ReactTestRenderer.create(null); + ReactTestRenderer.act(() => { + root.update(); + }); + expect(root).toMatchRenderedOutput('4'); + }); + it('warns for bad useImperativeHandle first arg', () => { const {useImperativeHandle} = React; function App() {