Home > OS >  Can't use useReducer Hook with in a Typescript Next Js project
Can't use useReducer Hook with in a Typescript Next Js project

Time:09-20

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;
}
  • Related