I am very new to Typescript and I am here trying to use the useReducer hook with Typescript.
This is my code:
import { useReducer, useContext, createContext } from "react"
import type { ReactNode } from "react"
const defaultState = { count: 0}
const CounterContext = createContext(undefined)
export type Action = 'increment' | 'decrement'
export type State = typeof defaultState
export type Dispatch = (action: Action) => void
const counterReducer = (state: State, action: Action) => {
switch(action) {
case 'increment': return state.count = state.count 1
case 'decrement': return state.count = state.count - 1
default: state
}
}
const CounterProvider = ({children}: {children: ReactNode}) => {
const [state, dispatch] = useReducer(counterReducer,defaultState)
...
}
I am getting an error in this line:
const [state, dispatch] = useReducer(counterReducer,defaultState)
Error is:
No overload matches this call.
Overload 1 of 5, '(reducer: ReducerWithoutAction<any>, initializerArg: any, initializer?: undefined): [any, DispatchWithoutAction]', gave the following error.
Argument of type '(state: State, action: Action) => number | undefined' is not assignable to parameter of type 'ReducerWithoutAction<any>'.
Overload 2 of 5, '(reducer: (state: { count: number; }, action: Action) => number | undefined, initialState: never, initializer?: undefined): [never, Dispatch<Action>]', gave the following error.
Argument of type '{ count: number; }' is not assignable to parameter of type 'never'.
Can you guys please tell me what I am doing wrong? Thanks.
CodePudding user response:
useReducer
is meant to return the updated state object (of the type {count: number}
).
The return
statements in your example return the result of the mathematical operation, which is just a number
, and the default
branch doesn't return
anything. As it is, your reducer returns number | undefined
.
Here's an example where the switch
first updates the state, which then gets returned at the end:
function counterReducer(state: State, action: Action): State {
switch (action) {
case 'increment':
state.count = 1;
break;
case 'decrement':
state.count -= 1;
break;
}
return state;
}