React createContext issue in Typescript? React createContext issue in Typescript? reactjs reactjs

React createContext issue in Typescript?


It appears defaultValue value for React.createContext is expected to be of type:

interface IContextProps {  state: IState;  dispatch: ({type}:{type:string}) => void;}

Once Context object is created for this type, for example like this:

export const AdminStore = React.createContext({} as IContextProps);

Provider React component should no longer complain about the error.

Here is the list of changes:

admin-store.tsx

import React, { useReducer } from "react";import { initialState, IState, reducer } from "./reducer";interface IContextProps {  state: IState;  dispatch: ({type}:{type:string}) => void;}export const AdminStore = React.createContext({} as IContextProps);export function AdminStoreProvider(props: any) {  const [state, dispatch] = useReducer(reducer, initialState);  const value = { state, dispatch };  return (    <AdminStore.Provider value={value}>{props.children}</AdminStore.Provider>  );}


I had a fun time with this so I figured I'd share what I came up with.

The SidebarProps represent the context's state. Everything else, besides the reducer actions, can essentially be used as is.

Here is a nice article explaining the exact same workaround (Not in TypeScript) : Mixing Hooks and Context Api

import React, { createContext, Dispatch, Reducer, useContext, useReducer } from 'react';interface Actions {    type: string;    value: any;}interface SidebarProps {    show: boolean;    content: JSX.Element | null;}interface SidebarProviderProps {    reducer: Reducer<SidebarProps, Actions>;    initState: SidebarProps;}interface InitContextProps {    state: SidebarProps;    dispatch: Dispatch<Actions>;}export const SidebarContext = createContext({} as InitContextProps);export const SidebarProvider: React.FC<SidebarProviderProps> = ({ reducer, initState, children }) => {    const [state, dispatch] = useReducer(reducer, initState);    const value = { state, dispatch };    return (        <SidebarContext.Provider value={value}>            {children}        </SidebarContext.Provider>    );};export const useSidebar = () => useContext(SidebarContext);const SidebarController: React.FC = ({ children }) => {    const initState: SidebarProps = {        show: false,        content: null    };    const reducer: Reducer<SidebarProps, Actions> = (state, action) => {        switch (action.type) {            case 'setShow':                return {                    ...state,                    show: action.value                };            case 'setContent':                return {                    ...state,                    content: action.value                };            default:                return state;        }    };    return (        <SidebarProvider reducer={reducer} initState={initState}>            {children}        </SidebarProvider>    );};export default SidebarController;