Skip to content

Commit

Permalink
some minor hooks updates (reduxjs#1294)
Browse files Browse the repository at this point in the history
* fix wrong inline documentation for useSelectors hook

* add test to get test coverage for useSelector to 100%

* add test to verify that docs suggestion of putting a connected component above the hooks component allows dealing with stale props
  • Loading branch information
MrWolfZ authored and timdorr committed Jun 11, 2019
1 parent 6e1c923 commit dd9886f
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 5 deletions.
7 changes: 3 additions & 4 deletions src/hooks/useSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
75 changes: 74 additions & 1 deletion test/hooks/useSelector.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -302,6 +303,78 @@ 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 <Child parentCount={count} />
}

const Child = ({ parentCount }) => {
const result = useSelector(({ count }) => {
if (parentCount > 0) {
throw new Error()
}

return count + parentCount
})

return <div>{result}</div>
}

rtl.render(
<ProviderMock store={store}>
<Parent />
</ProviderMock>
)

expect(() => store.dispatch({ type: '' })).toThrowError()

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 <ConnectedWrapper parentCount={count} />
}

const ConnectedWrapper = connect(({ count }) => ({ count }))(
({ parentCount }) => {
return <Child parentCount={parentCount} />
}
)

let sawInconsistentState = false

const Child = ({ parentCount }) => {
const result = useSelector(({ count }) => {
if (count !== parentCount) {
sawInconsistentState = true
}

return count + parentCount
})

return <div>{result}</div>
}

rtl.render(
<ProviderMock store={store}>
<Parent />
</ProviderMock>
)

store.dispatch({ type: '' })

expect(sawInconsistentState).toBe(false)

spy.mockRestore()
})
})

describe('error handling for invalid arguments', () => {
Expand Down

0 comments on commit dd9886f

Please sign in to comment.