Skip to content

Commit 69006eb

Browse files
committed
feat: Hook creators accept context directly
1 parent efd270f commit 69006eb

File tree

8 files changed

+33
-50
lines changed

8 files changed

+33
-50
lines changed

docs/api/hooks.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,19 +306,17 @@ To access an alternate context via the hooks API, use the hook creator functions
306306
import React from 'react'
307307
import {
308308
Provider,
309-
createReduxContextHook,
310309
createStoreHook,
311310
createDispatchHook,
312311
createSelectorHook
313312
} from 'react-redux'
314313

315314
const MyContext = React.createContext(null)
316-
const useMyReduxContext = createReduxContextHook(MyContext)
317315

318316
// Export your custom hooks if you wish to use them in other files.
319-
export const useStore = createStoreHook(useMyReduxContext)
320-
export const useDispatch = createDispatchHook(useMyReduxContext)
321-
export const useSelector = createSelectorHook(useMyReduxContext)
317+
export const useStore = createStoreHook(MyContext)
318+
export const useDispatch = createDispatchHook(MyContext)
319+
export const useSelector = createSelectorHook(MyContext)
322320

323321
const myStore = createStore(rootReducer)
324322

src/hooks/useDispatch.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
import { ReactReduxContext } from '../components/Context'
12
import { useStore as useDefaultStore, createStoreHook } from './useStore'
23

34
/**
45
* Hook factory, which creates a `useDispatch` hook bound to a given context.
56
*
6-
* @param {Function} [useReduxContext] Hook which returns the Redux context.
7+
* @param {Function} [context=ReactReduxContext] Context passed to your `<Provider>`.
78
* @returns {Function} A `useDispatch` hook bound to the specified context.
89
*/
9-
export function createDispatchHook(useReduxContext = null) {
10-
const useStore = useReduxContext
11-
? createStoreHook(useReduxContext)
12-
: useDefaultStore
10+
export function createDispatchHook(context = ReactReduxContext) {
11+
const useStore =
12+
context === ReactReduxContext ? useDefaultStore : createStoreHook(context)
1313
return function useDispatch() {
1414
const store = useStore()
1515
return store.dispatch

src/hooks/useReduxContext.js

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,11 @@ import { useContext } from 'react'
22
import invariant from 'invariant'
33
import { ReactReduxContext } from '../components/Context'
44

5-
/**
6-
* Hook factory, which creates a `useReduxContext` hook bound to a given context.
7-
*
8-
* @param {Function} [context=ReactReduxContext] React context passed to the `context` prop of your `<Provider>`.
9-
* @returns {Function} A `useReactContext` hook bound to the specified context.
10-
*/
11-
export function createReduxContextHook(context = ReactReduxContext) {
12-
return function useReduxContext() {
13-
const contextValue = useContext(context)
14-
15-
invariant(
16-
contextValue,
17-
'could not find react-redux context value; please ensure the component is wrapped in a <Provider>'
18-
)
19-
20-
return contextValue
21-
}
22-
}
23-
245
/**
256
* A hook to access the value of the `ReactReduxContext`. This is a low-level
267
* hook that you should usually not need to call directly.
278
*
9+
* @param {Function} [context=ReactReduxContext] Context passed to your `<Provider>`, if you're not using the default.
2810
* @returns {any} the value of the `ReactReduxContext`
2911
*
3012
* @example
@@ -37,4 +19,13 @@ export function createReduxContextHook(context = ReactReduxContext) {
3719
* return <div>{store.getState()}</div>
3820
* }
3921
*/
40-
export const useReduxContext = createReduxContextHook()
22+
export function useReduxContext(context = ReactReduxContext) {
23+
const contextValue = useContext(context)
24+
25+
invariant(
26+
contextValue,
27+
'could not find react-redux context value; please ensure the component is wrapped in a <Provider>'
28+
)
29+
30+
return contextValue
31+
}

src/hooks/useSelector.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { useReducer, useRef, useEffect, useMemo, useLayoutEffect } from 'react'
22
import invariant from 'invariant'
3-
import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
3+
import { useReduxContext } from './useReduxContext'
44
import Subscription from '../utils/Subscription'
5+
import { ReactReduxContext } from '../components/Context'
56

67
// React currently throws a warning when using useLayoutEffect on the server.
78
// To get around it, we can conditionally useEffect on the server (no-op) and
@@ -95,14 +96,14 @@ function useSelectorWithStoreAndSubscription(
9596
/**
9697
* Hook factory, which creates a `useSelector` hook bound to a given context.
9798
*
98-
* @param {Function} [useReduxContext] Hook which returns the Redux context.
99+
* @param {Function} [context=ReactReduxContext] Context passed to your `<Provider>`.
99100
* @returns {Function} A `useSelector` hook bound to the specified context.
100101
*/
101-
export function createSelectorHook(useReduxContext = useDefaultReduxContext) {
102+
export function createSelectorHook(context = ReactReduxContext) {
102103
return function useSelector(selector, equalityFn = refEquality) {
103104
invariant(selector, `You must pass a selector to useSelectors`)
104105

105-
const { store, subscription: contextSub } = useReduxContext()
106+
const { store, subscription: contextSub } = useReduxContext(context)
106107

107108
return useSelectorWithStoreAndSubscription(
108109
selector,

src/hooks/useStore.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
1+
import { ReactReduxContext } from '../components/Context'
2+
import { useReduxContext } from './useReduxContext'
23

34
/**
45
* Hook factory, which creates a `useStore` hook bound to a given context.
56
*
6-
* @param {Function} [useReduxContext] Hook which returns the Redux context.
7+
* @param {Function} [context=ReactReduxContext] Context passed to your `<Provider>`.
78
* @returns {Function} A `useStore` hook bound to the specified context.
89
*/
9-
export function createStoreHook(useReduxContext = useDefaultReduxContext) {
10+
export function createStoreHook(context = ReactReduxContext) {
1011
return function useStore() {
11-
const { store } = useReduxContext()
12+
const { store } = useReduxContext(context)
1213
return store
1314
}
1415
}

src/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import connect from './connect/connect'
66
import { useDispatch, createDispatchHook } from './hooks/useDispatch'
77
import { useSelector, createSelectorHook } from './hooks/useSelector'
88
import { useStore, createStoreHook } from './hooks/useStore'
9-
import { createReduxContextHook } from './hooks/useReduxContext'
109

1110
import { setBatch } from './utils/batch'
1211
import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates'
@@ -26,6 +25,5 @@ export {
2625
createSelectorHook,
2726
useStore,
2827
createStoreHook,
29-
createReduxContextHook,
3028
shallowEqual
3129
}

test/hooks/useDispatch.spec.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { renderHook } from 'react-hooks-testing-library'
44
import {
55
Provider as ProviderMock,
66
useDispatch,
7-
createDispatchHook,
8-
createReduxContextHook
7+
createDispatchHook
98
} from '../../src/index.js'
109

1110
const store = createStore(c => c + 1)
@@ -25,9 +24,7 @@ describe('React', () => {
2524
describe('createDispatchHook', () => {
2625
it("returns the correct store's dispatch function", () => {
2726
const nestedContext = React.createContext(null)
28-
const useCustomDispatch = createDispatchHook(
29-
createReduxContextHook(nestedContext)
30-
)
27+
const useCustomDispatch = createDispatchHook(nestedContext)
3128
const { result } = renderHook(() => useDispatch(), {
3229
// eslint-disable-next-line react/prop-types
3330
wrapper: ({ children, ...props }) => (

test/hooks/useSelector.spec.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import {
99
useSelector,
1010
shallowEqual,
1111
connect,
12-
createSelectorHook,
13-
createReduxContextHook
12+
createSelectorHook
1413
} from '../../src/index.js'
1514
import { useReduxContext } from '../../src/hooks/useReduxContext'
1615

@@ -403,9 +402,7 @@ describe('React', () => {
403402

404403
it('subscribes to the correct store', () => {
405404
const nestedContext = React.createContext(null)
406-
const useCustomSelector = createSelectorHook(
407-
createReduxContextHook(nestedContext)
408-
)
405+
const useCustomSelector = createSelectorHook(nestedContext)
409406
let defaultCount = null
410407
let customCount = null
411408

0 commit comments

Comments
 (0)