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 6bcfdcc4..5dfe4f5d 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 19fb03f4..61511b24 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 5dfe4f5d..76deb240 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 61511b24..aab78ac3 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 76deb240..0a828cca 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 aab78ac3..bd3254df 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 +); ```