Skip to content

Commit

Permalink
Merge pull request #3995 from reduxjs/migration-context-typing
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Dec 19, 2023
2 parents 4afef4a + 1f9deb2 commit 7978bbb
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions docs/usage/migrating-rtk-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,58 @@ React-Redux v7 and v8 worked with all versions of React that supported hooks (16

**React-Redux v9 switches to _requiring_ React 18, and does _not_ support React 16 or 17**. This allows us to drop the shim and save a small bit of bundle size.

<div class="typescript-only">

#### Custom context typing

React Redux supports creating `hooks` (and `connect`) with a [custom context](https://react-redux.js.org/api/hooks#custom-context), but typing this has been fairly non-standard. The pre-v9 types required `Context<ReactReduxContextValue>`, but the context default value was usually initialised with `null` (as the hooks use this to make sure they actually have a provided context). This, in "best" cases, would result in something like the below:

```ts title="Pre-v9 custom context"
import { createContext } from 'react'
import {
ReactReduxContextValue,
TypedUseSelectorHook,
createDispatchHook,
createSelectorHook,
createStoreHook,
} from 'react-redux'
import { AppStore, RootState, AppDispatch } from './store'

// highlight-next-line
const context = createContext<ReactReduxContextValue>(null as any)

export const useStore: () => AppStore = createStoreHook(context)
export const useDispatch: () => AppDispatch = createDispatchHook(context)
export const useSelector: TypedUseSelectorHook<RootState> =
createSelectorHook(context)
```

In v9, the types now match the runtime behaviour. The context is typed to hold `ReactReduxContextValue | null`, and the hooks know that if they receive `null` they'll throw an error so it doesn't affect the return type.

The above example now becomes:

```ts title="v9+ custom context"
import { createContext } from 'react'
import {
ReactReduxContextValue,
TypedUseSelectorHook,
createDispatchHook,
createSelectorHook,
createStoreHook,
} from 'react-redux'
import { AppStore, RootState, AppDispatch } from './store'

// highlight-next-line
const context = createContext<ReactReduxContextValue | null>(null)

export const useStore: () => AppStore = createStoreHook(context)
export const useDispatch: () => AppDispatch = createDispatchHook(context)
export const useSelector: TypedUseSelectorHook<RootState> =
createSelectorHook(context)
```

</div>

### Redux Thunk

#### Thunk Uses Named Exports
Expand Down

0 comments on commit 7978bbb

Please sign in to comment.