0

I am not an expert on React so asking here. I wanted to create Application context with React.useContext API. Here is my easy sample code here:

import {
    createContext,
    FC,
    useCallback,
    useContext,
    useMemo,
    useReducer,
} from 'react'

type State = {
    modal: boolean,
    errorMessage: string | null,
}

type Action =
  | { type: 'TOGGLE_MODAL'}
  | { type: 'SET_ERROR'}

const initialState: State = {
    modal: false,
    errorMessage: null,
}

export const ApplicationContext = createContext(initialState)

export const useApplicationContext = () => {
    return useContext(ApplicationContext)
}

export const reducer = (state: State, { type, payload }) => {
  switch (type) {
    case 'TOGGLE_MODAL':
      const { modal } = payload
      return {
        ...state,
        modal,
      }
    case 'SET_ERROR':
      const { errorMessage } = payload
      return {
        ...state,
        errorMessage,
      }
    default: {
      throw Error(
        `Unexpected action type in ApplicationContext reducer: '${type}'.`
      )
    }
  }
}

const ApplicationContextProvider: FC = (props) => {
  const [state, dispatch] = useReducer(reducer, initialState)

  const toggleModal = useCallback((target) => {
    dispatch({ type: 'TOGGLE_MODAL', payload: { modal: target }})
  }, [])

  const setError = useCallback((message) => {
    dispatch({ type: 'SET_ERROR', payload: { errorMessage: message } })
  }, [])

  const value = useMemo(
    () => ({
      state,
      toggleModal,
      setError,
    }),
    [setError, state, toggleModal]
  )

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

export default ApplicationContextProvider

However when I compile the src, I get an error as follows:

Type '{ state: { modal: any; errorMessage: string | null; } | { errorMessage: any; modal: boolean; }; toggleModal: (target: any) => void; setError: (message: any) => void; }' is missing the following properties from type 'State': modal, errorMessage  TS2739

So I'm trying to understand what this error tries to tell but totally no idea. Can anyone help with this?

user76333
  • 153
  • 1
  • 13

1 Answers1

0

The line of the error would also be relevant, but I could find it anyway

Type '{ state: { modal: any; errorMessage: string | null; } | { errorMessage: any; modal: boolean; }; toggleModal: (target: any) => void; setError: (message: any) => void; }' is missing the following properties from type 'State': modal, errorMessage  TS2739

What this error is saying is that you are trying to set an object with properties state, toggleModal and setError to a State param, which needs the properties modal and errorMessage. Typescript is just telling you that you are trying to use the incorrect value, and that if you try to run it it will just not work.

The problem is here:

export const ApplicationContext = createContext(initialState)

// ...

const value = useMemo(
  () => ({
    state,
    toggleModal,
    setError,
  }),
  [setError, state, toggleModal]
)

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

ApplicationContext is intialized as a React.Context whose value is State. But when you try to set the value, you are setting it to an object with { state, toggleModal, setError } which does not match State.

Solution - Either pass in value={state} instead, or initialize the context with createContext({ toggleModal: () => {}, setError: () => {}, state: initialState })

olivarra1
  • 3,269
  • 3
  • 23
  • 34