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

Add section re: RR custom context typing change #3995

Merged
merged 2 commits into from
Dec 19, 2023
Merged
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
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