Chris
Chris

Reputation: 33

Typescript React UseReducer Type Error on Provider Value

I am currently running into errors getting my provider working using the React Context API in Typescript, I am getting the following error,

Type '{ state: { hasEnterPressed: boolean; searchQuery: string; }; dispatch: Dispatch<stringAction>; }' 
is missing the following properties from type '{ hasEnterPressed: boolean; searchQuery: string; dispatch: 
(state: { hasEnterPressed: boolean; searchQuery: string; }, action: stringAction) => 
{ hasEnterPressed: boolean; searchQuery: string; }; }': hasEnterPressed, searchQuery  TS2739

    50 | 
    51 |     return (
  > 52 |         <SearchContext.Provider value={value}>
       |                                 ^
    53 |             {props.children}
    54 |         </SearchContext.Provider>
    55 |     )





I believe it is related to the construction of my CreateContext call which is the reason I might be running into issues. I have tried building interface types but I am still getting the same error.

import React, {useReducer, createContext, Dispatch}  from "react";


export interface Action {
    type: string
}

export interface stringAction extends Action {
    payload: string
}

export interface reducerState {
    hasEnterPressed: boolean
    searchQuery: string,
}


const reducer = (state: reducerState, action: stringAction) => {
    switch(action.type) {
        case "UPDATEKEYPRESS":
            return {
                ...state,
                hasEnterPressed: false
            };
        case "UPDATESEARCHQUERY":
            return {
                ...state,
                searchQuery: action.payload
            }
        default:
            throw new Error();
    }
}

const initalState: reducerState = {
    hasEnterPressed: false,
    searchQuery : '',
}


export const SearchContext = createContext<reducerState>(initalState);

export const SearchProvider: React.FC = (props) => {

    const [state, dispatch] = useReducer(reducer, initalState)

    const value = {state, dispatch}

    return (
        <SearchContext.Provider value={value}>
            {props.children}
        </SearchContext.Provider>
    )
}

export default SearchProvider;


Upvotes: 3

Views: 627

Answers (1)

Shlang
Shlang

Reputation: 3230

value you are passing in is an object {state, dispatch} while createContext<reducerState> makes provider expecting it to be reducerState.

You need to either change the type of context to

interface SearchContextValue {
  state: reducerState; 
  dispatch: Dispatch<ReducerAction<typeof reducer>>
}

export const SearchContext = createContext<SearchContextValue>({
 state: initalState, 
 dispatch: () => {} // fake, but it is not possible to provide at this point 
});

or if you don't need to pass a dispatch – pass the state as the value

<SearchContext.Provider value={state}>

Please note that it is a good practice to capitalize types' names otherwise it gets hard to distinguish them with variables' names.

Upvotes: 3

Related Questions