Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some minor hooks updates #1294

Merged
merged 3 commits into from May 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/hooks/useSelector.js
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
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