From 05c0d5b4bea61a46f52d9f90f4cd46a7ccacbd0c Mon Sep 17 00:00:00 2001 From: Jonathan Ziller Date: Sat, 25 May 2019 11:31:41 +0200 Subject: [PATCH 1/3] fix wrong inline documentation for useSelectors hook --- src/hooks/useSelector.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hooks/useSelector.js b/src/hooks/useSelector.js index 83e48569d..62171b3ee 100644 --- a/src/hooks/useSelector.js +++ b/src/hooks/useSelector.js @@ -20,9 +20,9 @@ const refEquality = (a, b) => a === b * A hook to access the redux store's state. This hook takes a selector function * as an argument. The selector is called with the store state. * - * This hook takes a dependencies array as an optional second argument, - * which when passed ensures referential stability of the selector (this is primarily - * useful if you provide a selector that memoizes values). + * This hook takes an optional equality comparison function as the second parameter + * that allows you to customize the way the selected state is compared to determine + * whether the component needs to be re-rendered. * * @param {Function} selector the selector function * @param {Function} equalityFn the function that will be used to determine equality @@ -33,7 +33,6 @@ const refEquality = (a, b) => a === b * * import React from 'react' * import { useSelector } from 'react-redux' - * import { RootState } from './store' * * export const CounterComponent = () => { * const counter = useSelector(state => state.counter) From 9c1b6a92cd77c1f580513b8433ff4d269b4d048e Mon Sep 17 00:00:00 2001 From: Jonathan Ziller Date: Sat, 25 May 2019 11:32:21 +0200 Subject: [PATCH 2/3] add test to get test coverage for useSelector to 100% --- test/hooks/useSelector.spec.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/hooks/useSelector.spec.js b/test/hooks/useSelector.spec.js index a4756d244..79b8327c4 100644 --- a/test/hooks/useSelector.spec.js +++ b/test/hooks/useSelector.spec.js @@ -302,6 +302,37 @@ describe('React', () => { spy.mockRestore() }) + + it('re-throws errors from the selector that only occur during rendering', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + + const Parent = () => { + const count = useSelector(s => s.count) + return + } + + const Child = ({ parentCount }) => { + const result = useSelector(({ count }) => { + if (parentCount > 0) { + throw new Error() + } + + return count + parentCount + }) + + return
{result}
+ } + + rtl.render( + + + + ) + + expect(() => store.dispatch({ type: '' })).toThrowError() + + spy.mockRestore() + }) }) describe('error handling for invalid arguments', () => { From 7626018a4b030a4357218edd7b578dcbbbecf027 Mon Sep 17 00:00:00 2001 From: Jonathan Ziller Date: Sat, 25 May 2019 11:51:07 +0200 Subject: [PATCH 3/3] add test to verify that docs suggestion of putting a connected component above the hooks component allows dealing with stale props --- test/hooks/useSelector.spec.js | 44 +++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/test/hooks/useSelector.spec.js b/test/hooks/useSelector.spec.js index 79b8327c4..fdaffdba4 100644 --- a/test/hooks/useSelector.spec.js +++ b/test/hooks/useSelector.spec.js @@ -7,7 +7,8 @@ import * as rtl from 'react-testing-library' import { Provider as ProviderMock, useSelector, - shallowEqual + shallowEqual, + connect } from '../../src/index.js' import { useReduxContext } from '../../src/hooks/useReduxContext' @@ -333,6 +334,47 @@ describe('React', () => { spy.mockRestore() }) + + it('allows dealing with stale props by putting a specific connected component above the hooks component', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + + const Parent = () => { + const count = useSelector(s => s.count) + return + } + + const ConnectedWrapper = connect(({ count }) => ({ count }))( + ({ parentCount }) => { + return + } + ) + + let sawInconsistentState = false + + const Child = ({ parentCount }) => { + const result = useSelector(({ count }) => { + if (count !== parentCount) { + sawInconsistentState = true + } + + return count + parentCount + }) + + return
{result}
+ } + + rtl.render( + + + + ) + + store.dispatch({ type: '' }) + + expect(sawInconsistentState).toBe(false) + + spy.mockRestore() + }) }) describe('error handling for invalid arguments', () => {