From fd4470105a727f48fd3173da1adb30f8a2607f79 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 14 Feb 2026 00:46:09 +0100 Subject: [PATCH 1/3] Add missing return to reducer as recommended in section before code example --- README.md | 2 +- docs/basic/getting-started/hooks.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6bcfdcc4c..5dfe4f5d8 100644 --- a/README.md +++ b/README.md @@ -384,7 +384,7 @@ type ACTIONTYPE = | { type: "increment"; payload: number } | { type: "decrement"; payload: string }; -function reducer(state: typeof initialState, action: ACTIONTYPE) { +function reducer(state: typeof initialState, action: ACTIONTYPE): typeof initialState { switch (action.type) { case "increment": return { count: state.count + action.payload }; diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 19fb03f47..61511b24c 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -93,7 +93,7 @@ type ACTIONTYPE = | { type: "increment"; payload: number } | { type: "decrement"; payload: string }; -function reducer(state: typeof initialState, action: ACTIONTYPE) { +function reducer(state: typeof initialState, action: ACTIONTYPE): typeof initialState { switch (action.type) { case "increment": return { count: state.count + action.payload }; From 5ec993033a4c9139ae6dc93a7060da3cb222a0d4 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 14 Feb 2026 01:12:06 +0100 Subject: [PATCH 2/3] Added section on manual typing for useReducer --- README.md | 12 ++++++++++++ docs/basic/getting-started/hooks.md | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/README.md b/README.md index 5dfe4f5d8..76deb240f 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,18 @@ export function reducer: Reducer() {} +
+ +Providing explicit types for useReducer + +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. + +```tsx +const [state, dispatch] = useReducer(reducer, initialState); +``` + +
+ #### useEffect / useLayoutEffect Both of `useEffect` and `useLayoutEffect` are used for performing side effects 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: diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 61511b24c..aab78ac32 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -138,6 +138,18 @@ export function reducer: Reducer() {} +
+ +Providing explicit types for useReducer + +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. + +```tsx +const [state, dispatch] = useReducer(reducer, initialState); +``` + +
+ ## useEffect / useLayoutEffect Both of `useEffect` and `useLayoutEffect` are used for performing side effects 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: From 3f8ea7a66e7d82f9c4a4165f21e261f0feb2b6c7 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 14 Feb 2026 01:26:43 +0100 Subject: [PATCH 3/3] Formatter fix --- README.md | 10 ++++++++-- docs/basic/getting-started/hooks.md | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 76deb240f..0a828cca0 100644 --- a/README.md +++ b/README.md @@ -384,7 +384,10 @@ type ACTIONTYPE = | { type: "increment"; payload: number } | { type: "decrement"; payload: string }; -function reducer(state: typeof initialState, action: ACTIONTYPE): typeof initialState { +function reducer( + state: typeof initialState, + action: ACTIONTYPE +): typeof initialState { switch (action.type) { case "increment": return { count: state.count + action.payload }; @@ -436,7 +439,10 @@ export function reducer: Reducer() {} 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. ```tsx -const [state, dispatch] = useReducer(reducer, initialState); +const [state, dispatch] = useReducer( + reducer, + initialState +); ``` diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index aab78ac32..bd3254df4 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -93,7 +93,10 @@ type ACTIONTYPE = | { type: "increment"; payload: number } | { type: "decrement"; payload: string }; -function reducer(state: typeof initialState, action: ACTIONTYPE): typeof initialState { +function reducer( + state: typeof initialState, + action: ACTIONTYPE +): typeof initialState { switch (action.type) { case "increment": return { count: state.count + action.payload }; @@ -145,7 +148,10 @@ export function reducer: Reducer() {} 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. ```tsx -const [state, dispatch] = useReducer(reducer, initialState); +const [state, dispatch] = useReducer( + reducer, + initialState +); ```