From 3146b358e4e24ccfc708df8e80210556ee860f15 Mon Sep 17 00:00:00 2001 From: Tim Dorr Date: Thu, 25 Mar 2021 09:57:19 -0400 Subject: [PATCH 1/2] Don't re-run the selector after update Fixes #1697 We can avoid running the selector twice by setting the latestStoreState at the same time as setting the latestSelectedState. If the store state hasn't changed, then the selector won't as well (since it's pure). --- src/hooks/useSelector.js | 4 +++- test/hooks/useSelector.spec.js | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hooks/useSelector.js b/src/hooks/useSelector.js index 39066e776..410aac414 100644 --- a/src/hooks/useSelector.js +++ b/src/hooks/useSelector.js @@ -64,13 +64,15 @@ function useSelectorWithStoreAndSubscription( useIsomorphicLayoutEffect(() => { function checkForUpdates() { try { - const newSelectedState = latestSelector.current(store.getState()) + const storeState = store.getState() + const newSelectedState = latestSelector.current(storeState) if (equalityFn(newSelectedState, latestSelectedState.current)) { return } latestSelectedState.current = newSelectedState + latestStoreState.current = storeState } catch (err) { // we ignore all errors here, since when the component // is re-rendered, the selectors are called again, and diff --git a/test/hooks/useSelector.spec.js b/test/hooks/useSelector.spec.js index 3a0fcfd7d..0af0176c7 100644 --- a/test/hooks/useSelector.spec.js +++ b/test/hooks/useSelector.spec.js @@ -38,17 +38,21 @@ describe('React', () => { }) it('selects the state and renders the component when the store updates', () => { - const { result } = renderHook(() => useSelector((s) => s.count), { + const selector = jest.fn((s) => s.count) + + const { result } = renderHook(() => useSelector(selector), { wrapper: (props) => , }) expect(result.current).toEqual(0) + expect(selector).toHaveBeenCalledTimes(2) act(() => { store.dispatch({ type: '' }) }) expect(result.current).toEqual(1) + expect(selector).toHaveBeenCalledTimes(3) }) }) From b92a13991b48eafb97463af9216a4c7c99661c47 Mon Sep 17 00:00:00 2001 From: Tim Dorr Date: Thu, 25 Mar 2021 09:58:56 -0400 Subject: [PATCH 2/2] Avoid variable naming conflicts --- src/hooks/useSelector.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/useSelector.js b/src/hooks/useSelector.js index 410aac414..87b61f244 100644 --- a/src/hooks/useSelector.js +++ b/src/hooks/useSelector.js @@ -64,15 +64,15 @@ function useSelectorWithStoreAndSubscription( useIsomorphicLayoutEffect(() => { function checkForUpdates() { try { - const storeState = store.getState() - const newSelectedState = latestSelector.current(storeState) + const newStoreState = store.getState() + const newSelectedState = latestSelector.current(newStoreState) if (equalityFn(newSelectedState, latestSelectedState.current)) { return } latestSelectedState.current = newSelectedState - latestStoreState.current = storeState + latestStoreState.current = newStoreState } catch (err) { // we ignore all errors here, since when the component // is re-rendered, the selectors are called again, and