Skip to content

Commit 168469a

Browse files
authored
Enhance useReducer example and add section on explicit typing (#800)
* Add missing return to reducer as recommended in section before code example * Added section on manual typing for useReducer * Formatter fix
1 parent 52f70c3 commit 168469a

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@ type ACTIONTYPE =
384384
| { type: "increment"; payload: number }
385385
| { type: "decrement"; payload: string };
386386

387-
function reducer(state: typeof initialState, action: ACTIONTYPE) {
387+
function reducer(
388+
state: typeof initialState,
389+
action: ACTIONTYPE
390+
): typeof initialState {
388391
switch (action.type) {
389392
case "increment":
390393
return { count: state.count + action.payload };
@@ -429,6 +432,21 @@ export function reducer: Reducer<AppState, Action>() {}
429432

430433
</details>
431434

435+
<details>
436+
437+
<summary><b>Providing explicit types for <code>useReducer</code></b></summary>
438+
439+
In most cases, type inference for useReducer should work reliably. When inference fails, the state and action types can be explicitly provided using the following syntax, where the action type is wrapped in a single-element tuple.
440+
441+
```tsx
442+
const [state, dispatch] = useReducer<typeof initialState, [ACTIONTYPE]>(
443+
reducer,
444+
initialState
445+
);
446+
```
447+
448+
</details>
449+
432450
#### useEffect / useLayoutEffect
433451

434452
Both of `useEffect` and `useLayoutEffect` are used for performing <b>side effects</b> and return an optional cleanup function which means if they don't deal with returning values, no types are necessary. When using `useEffect`, take care not to return anything other than a function or `undefined`, otherwise both TypeScript and React will yell at you. This can be subtle when using arrow functions:

docs/basic/getting-started/hooks.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ type ACTIONTYPE =
9393
| { type: "increment"; payload: number }
9494
| { type: "decrement"; payload: string };
9595

96-
function reducer(state: typeof initialState, action: ACTIONTYPE) {
96+
function reducer(
97+
state: typeof initialState,
98+
action: ACTIONTYPE
99+
): typeof initialState {
97100
switch (action.type) {
98101
case "increment":
99102
return { count: state.count + action.payload };
@@ -138,6 +141,21 @@ export function reducer: Reducer<AppState, Action>() {}
138141

139142
</details>
140143

144+
<details>
145+
146+
<summary><b>Providing explicit types for <code>useReducer</code></b></summary>
147+
148+
In most cases, type inference for useReducer should work reliably. When inference fails, the state and action types can be explicitly provided using the following syntax, where the action type is wrapped in a single-element tuple.
149+
150+
```tsx
151+
const [state, dispatch] = useReducer<typeof initialState, [ACTIONTYPE]>(
152+
reducer,
153+
initialState
154+
);
155+
```
156+
157+
</details>
158+
141159
## useEffect / useLayoutEffect
142160

143161
Both of `useEffect` and `useLayoutEffect` are used for performing <b>side effects</b> and return an optional cleanup function which means if they don't deal with returning values, no types are necessary. When using `useEffect`, take care not to return anything other than a function or `undefined`, otherwise both TypeScript and React will yell at you. This can be subtle when using arrow functions:

0 commit comments

Comments
 (0)