From 1f7d10e2a11828db23e81e8e3eedfc2bbe177a2c Mon Sep 17 00:00:00 2001 From: eps1lon Date: Mon, 3 May 2021 23:20:18 +0200 Subject: [PATCH 1/2] test: Add current behavior for reducers --- .../ReactHooksWithNoopRenderer-test.js | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js index fc5e61cd78ee6..a8940c781bd10 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js @@ -3784,4 +3784,49 @@ describe('ReactHooksWithNoopRenderer', () => { expect(Scheduler).toHaveYielded(['Render: 0']); }); + + it('reducer-closure', () => { + let setLimit; + let increment; + function Test() { + const [limit, _setLimit] = useState(5); + const [count, _increment] = useReducer((state, action) => { + return state < limit ? state + 1 : state; + }, 1); + setLimit = _setLimit; + increment = _increment; + + return ; + } + + act(() => { + ReactNoop.render(); + }); + + expect(Scheduler).toHaveYielded(['Render: 1']); + + act(() => { + increment(); + increment(); + increment(); + increment(); + }); + + expect(Scheduler).toHaveYielded(['Render: 5']); + + act(() => { + increment(); + }); + act(() => { + increment(); + }); + + expect(Scheduler).toHaveYielded([]); + + act(() => { + setLimit(10); + }); + + expect(Scheduler).toHaveYielded(['Render: 5']); + }); }); From 2a092aeb5dda444b93dc0eddc6229d5a7ebbd25b Mon Sep 17 00:00:00 2001 From: eps1lon Date: Mon, 3 May 2021 23:27:21 +0200 Subject: [PATCH 2/2] Naive fix --- packages/react-reconciler/src/ReactFiberHooks.new.js | 4 +++- packages/react-reconciler/src/ReactFiberHooks.old.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberHooks.new.js b/packages/react-reconciler/src/ReactFiberHooks.new.js index b195a0cb57488..ea4312394c87b 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.new.js +++ b/packages/react-reconciler/src/ReactFiberHooks.new.js @@ -821,7 +821,9 @@ function updateReducer( newState = ((update.eagerState: any): S); } else { const action = update.action; - newState = reducer(newState, action); + const reducerImpl = + update.eagerReducer !== null ? update.eagerReducer : reducer; + newState = reducerImpl(newState, action); } } update = update.next; diff --git a/packages/react-reconciler/src/ReactFiberHooks.old.js b/packages/react-reconciler/src/ReactFiberHooks.old.js index 7c51c43ad2e7e..e2be5a96d5c97 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.old.js +++ b/packages/react-reconciler/src/ReactFiberHooks.old.js @@ -821,7 +821,9 @@ function updateReducer( newState = ((update.eagerState: any): S); } else { const action = update.action; - newState = reducer(newState, action); + const reducerImpl = + update.eagerReducer !== null ? update.eagerReducer : reducer; + newState = reducerImpl(newState, action); } } update = update.next;