Skip to content

Commit 75cee54

Browse files
committed
Reduce the TypeScript page to typing connect and move it to the Legacy group
The hooks setup and manual hook typing now live on the core Usage with TypeScript page.
1 parent 962c6bc commit 75cee54

3 files changed

Lines changed: 15 additions & 142 deletions

File tree

Lines changed: 11 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,22 @@
11
---
22
id: usage-with-typescript
3-
title: Usage with TypeScript
3+
title: Typing connect with TypeScript
44
hide_title: true
5-
sidebar_label: Usage with TypeScript
6-
description: 'Usage > TypeScript: how to correctly type React Redux APIs'
5+
sidebar_label: 'Connect: Usage with TypeScript'
6+
description: 'Usage > TypeScript: how to type the legacy connect API'
77
---
88

99
 
1010

11-
# Usage with TypeScript
11+
# Typing `connect` with TypeScript
1212

13-
As of React-Redux v8, React-Redux is fully written in TypeScript, and the types are included in the published package. The types also export some helpers to make it easier to write typesafe interfaces between your Redux store and your React components.
13+
:::warning Deprecated
1414

15-
:::info
16-
17-
The recently updated `@types/react@18` major version has changed component definitions to remove having `children` as a prop by default. This causes errors if you have multiple copies of `@types/react` in your project. To fix this, tell your package manager to resolve `@types/react` to a single version. Details:
18-
19-
https://github.com/facebook/react/issues/24304#issuecomment-1094565891
15+
`connect` is marked as deprecated as of React-Redux 9.3.0. It still works, and we do not intend to remove it, but [**we recommend using the hooks API instead**](../api/hooks.md). The hooks are also much simpler to type. For the standard TypeScript setup with `RootState`, `AppDispatch`, and pre-typed `useAppSelector` / `useAppDispatch` hooks, see [**Usage with TypeScript**](/usage/usage-with-typescript) in the Redux docs.
2016

2117
:::
2218

23-
## Standard Redux Toolkit Project Setup with TypeScript
24-
25-
We assume that a typical Redux project is using Redux Toolkit and React Redux together.
26-
27-
[Redux Toolkit](https://redux-toolkit.js.org) (RTK) is the standard approach for writing modern Redux logic. RTK is already written in TypeScript, and its API is designed to provide a good experience for TypeScript usage.
28-
29-
The [Redux+TS template for Vite](https://github.com/reduxjs/redux-templates/tree/master/packages/vite-template-redux) comes with a working example of these patterns already configured.
30-
31-
### Define Root State and Dispatch Types
32-
33-
Using [configureStore](https://redux-toolkit.js.org/api/configureStore) should not need any additional typings. You will, however, want to extract the `RootState` type and the `Dispatch` type so that they can be referenced as needed. Inferring these types from the store itself means that they correctly update as you add more state slices or modify middleware settings.
34-
35-
Since those are types, it's safe to export them directly from your store setup file such as `app/store.ts` and import them directly into other files.
36-
37-
```ts title="app/store.ts"
38-
import { configureStore } from '@reduxjs/toolkit'
39-
// ...
40-
41-
const store = configureStore({
42-
reducer: {
43-
posts: postsReducer,
44-
comments: commentsReducer,
45-
users: usersReducer,
46-
},
47-
})
48-
49-
// highlight-start
50-
// Infer the `RootState` and `AppDispatch` types from the store itself
51-
export type RootState = ReturnType<typeof store.getState>
52-
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
53-
export type AppDispatch = typeof store.dispatch
54-
// highlight-end
55-
```
56-
57-
### Define Typed Hooks
58-
59-
While it's possible to import the `RootState` and `AppDispatch` types into each component, it's better to **create pre-typed versions of the `useDispatch` and `useSelector` hooks for usage in your application**. This is important for a couple reasons:
60-
61-
- For `useSelector`, it saves you the need to type `(state: RootState)` every time
62-
- For `useDispatch`, the default `Dispatch` type does not know about thunks or other middleware. In order to correctly dispatch thunks, you need to use the specific customized `AppDispatch` type from the store that includes the thunk middleware types, and use that with `useDispatch`. Adding a pre-typed `useDispatch` hook keeps you from forgetting to import `AppDispatch` where it's needed.
63-
64-
Since these are actual variables, not types, it's important to define them in a separate file such as `app/hooks.ts`, not the store setup file. This allows you to import them into any component file that needs to use the hooks, and avoids potential circular import dependency issues.
65-
66-
#### `.withTypes()`
67-
68-
Previously, the approach for "pre-typing" hooks with your app setting was a little varied. The result would look something like the snippet below:
69-
70-
```ts title="app/hooks.ts"
71-
import type { TypedUseSelectorHook } from 'react-redux'
72-
import { useDispatch, useSelector, useStore } from 'react-redux'
73-
import type { AppDispatch, AppStore, RootState } from './store'
74-
75-
// highlight-start
76-
// Use throughout your app instead of plain `useDispatch` and `useSelector`
77-
export const useAppDispatch: () => AppDispatch = useDispatch
78-
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
79-
export const useAppStore: () => AppStore = useStore
80-
// highlight-end
81-
```
82-
83-
React Redux v9.1.0 adds a new `.withTypes` method to each of these hooks, analogous to the [`.withTypes`](https://redux-toolkit.js.org/usage/usage-with-typescript#defining-a-pre-typed-createasyncthunk) method found on Redux Toolkit's `createAsyncThunk`.
84-
85-
The setup now becomes:
86-
87-
```ts title="app/hooks.ts"
88-
import { useDispatch, useSelector, useStore } from 'react-redux'
89-
import type { AppDispatch, AppStore, RootState } from './store'
90-
91-
// highlight-start
92-
// Use throughout your app instead of plain `useDispatch` and `useSelector`
93-
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
94-
export const useAppSelector = useSelector.withTypes<RootState>()
95-
export const useAppStore = useStore.withTypes<AppStore>()
96-
// highlight-end
97-
```
98-
99-
## Typing Hooks Manually
100-
101-
We recommend using the pre-typed `useAppSelector` and `useAppDispatch` hooks shown above. If you prefer not to use those, here is how to type the hooks by themselves.
102-
103-
### Typing the `useSelector` hook
104-
105-
When writing selector functions for use with `useSelector`, you should explicitly define the type of the `state` parameter. TS should be able to then infer the return type of the selector, which will be reused as the return type of the `useSelector` hook:
106-
107-
```ts
108-
interface RootState {
109-
isOn: boolean
110-
}
111-
112-
// TS infers type: (state: RootState) => boolean
113-
const selectIsOn = (state: RootState) => state.isOn
114-
115-
// TS infers `isOn` is boolean
116-
const isOn = useSelector(selectIsOn)
117-
```
118-
119-
This can also be done inline as well:
120-
121-
```ts
122-
const isOn = useSelector((state: RootState) => state.isOn)
123-
```
124-
125-
### Typing the `useDispatch` hook
126-
127-
By default, the return value of `useDispatch` is the standard `Dispatch` type defined by the Redux core types, so no declarations are needed:
128-
129-
```ts
130-
const dispatch = useDispatch()
131-
```
132-
133-
If you have a customized version of the `Dispatch` type, you may use that type explicitly:
134-
135-
```ts
136-
// store.ts
137-
export type AppDispatch = typeof store.dispatch
138-
139-
// MyComponent.tsx
140-
const dispatch: AppDispatch = useDispatch()
141-
```
19+
React-Redux is written in TypeScript, and the types are included in the published package. This page covers the patterns for typing the `connect` higher-order component.
14220

14321
## Typing the `connect` higher order component
14422

@@ -271,15 +149,12 @@ However, inferring the type of `mapDispatch` this way will break if it is define
271149
272150
## Recommendations
273151
274-
The hooks API is generally simpler to use with static types. **If you're looking for the easiest solution for using static types with React-Redux, use the hooks API.**
275-
276152
If you're using `connect`, **we recommend using the `ConnectedProps<T>` approach for inferring the props from Redux**, as that requires the fewest explicit type declarations.
277153
278-
## Resources
154+
If you're able to migrate, the hooks API is simpler to type. See [Migrating to Modern Redux: Modernizing React Components](/usage/migrating-to-modern-redux#modernizing-react-components-with-react-redux) for how to convert `connect` usage to hooks.
279155
280-
For additional information, see these additional resources:
156+
## Resources
281157
282-
- [Redux docs: Usage with TypeScript](/usage/usage-with-typescript): Examples of how to use Redux Toolkit, the Redux core, and React Redux with TypeScript
158+
- [Redux docs: Usage with TypeScript](/usage/usage-with-typescript): the standard TypeScript setup for Redux Toolkit and the React-Redux hooks
283159
- [Redux docs: Quick Start](/tutorials/quick-start): shows how to use RTK and the React-Redux hooks API with TypeScript
284-
- [React+TypeScript Cheatsheet](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet): a comprehensive guide to using React with TypeScript
285-
- [React + Redux in TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide): extensive information on patterns for using React and Redux with TypeScript
160+
- [React+TypeScript Cheatsheet](https://github.com/typescript-cheatsheets/react): a comprehensive guide to using React with TypeScript

website/docusaurus.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ const siteConfig: Config = {
112112
position: 'right',
113113
},
114114
{
115-
to: 'using-react-redux/usage-with-typescript',
115+
to: 'using-react-redux/accessing-store',
116116
label: 'Using React Redux',
117117
position: 'right',
118118
},
@@ -148,7 +148,7 @@ const siteConfig: Config = {
148148
},
149149
{
150150
label: 'Using React Redux',
151-
to: 'using-react-redux/usage-with-typescript',
151+
to: 'using-react-redux/accessing-store',
152152
},
153153
{
154154
label: 'API Reference',

website/sidebars.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ const sidebars: SidebarsConfig = {
2727
type: 'category',
2828
label: 'Using React Redux',
2929
collapsed: false,
30-
items: [
31-
'using-react-redux/usage-with-typescript',
32-
'using-react-redux/accessing-store',
33-
],
30+
items: ['using-react-redux/accessing-store'],
3431
},
3532
{
3633
type: 'category',
@@ -45,6 +42,7 @@ const sidebars: SidebarsConfig = {
4542
'api/connect',
4643
'using-react-redux/connect-mapstate',
4744
'using-react-redux/connect-mapdispatch',
45+
'using-react-redux/usage-with-typescript',
4846
'tutorials/connect',
4947
],
5048
},

0 commit comments

Comments
 (0)