0

I am creating a Context using useContext with TypeScript. I have a function into seperate file MovieDetailProvider.tsx as wrapper in my App.tsx file.

import { Context, MovieObject } from '../interfaces/interfaces'

export const MovieDetailContext = React.createContext<Context | {}>({})

const MovieDetailProvider: React.FC<React.ReactNode> = ({ children }) => {

    const [movieData, setMovieData] = React.useState<MovieObject | {}>({})

    return (
        <MovieDetailContext.Provider value={{movieData, setMovieData}}>
                {children}
        </MovieDetailContext.Provider>
    )
}

export default MovieDetailProvider

Here is Context and MovieObject Interfaces:

export interface Context {
    movieData: MovieObject,
    setMovieData: (movieData: MovieObject) => void
}

export interface MovieObject {
    loading: boolean,
    error: any,
    data: any
}

Also I have 2 components which are "Consumers" using hooks useContext for exchanging data. But when trying to get context with useContext like this:

import { MovieDetailContext } from './MovieDetailProvider'

const MovieDetail: React.FC = () => {

    const { movieData, setMovieData } = useContext<Context>(MovieDetailContext)
....

and

import { MovieDetailContext } from './MovieDetailProvider'


const MovieList:React.FC = () => {

    const { movieData, setMovieData } = useContext<Context>(MovieDetailContext)
....

I have an error in the same place (MovieDetailContext is underlined) in two files. The error is

TypeScript error in /home/glib/ReactCourse/graphql-project/client/src/components/MovieDetail.tsx(8,61):
Argument of type 'Context<{} | Context>' is not assignable to parameter of type 'Context<Context>'.
  The types of 'Provider.propTypes' are incompatible between these types.
    Type 'WeakValidationMap<ProviderProps<{} | Context>> | undefined' is not assignable to type 'WeakValidationMap<ProviderProps<Context>> | undefined'.
      Type 'WeakValidationMap<ProviderProps<{} | Context>>' is not assignable to type 'WeakValidationMap<ProviderProps<Context>>'.
        Types of property 'value' are incompatible.
          Type 'Validator<{} | Context> | undefined' is not assignable to type 'Validator<Context> | undefined'.
            Type 'Validator<{} | Context>' is not assignable to type 'Validator<Context>'.
              Type '{} | Context' is not assignable to type 'Context'.
                Type '{}' is not assignable to type 'Context'.  TS2345

I dont have much experirnce with Typescript and I dont have an idea how to fix this Context error. If anyone has an advice or solution please help: ) Thanks

P.S. This is my App.tsx file

imports...

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache()
})

const App: React.FC = () => {
  return (
    <ApolloProvider client={client}> 
      <MovieDetailProvider>
        <h1>Your Movie List</h1>
        <MovieList/>
        <AddMovie/>
        <MovieDetail/>
      </MovieDetailProvider>
    </ApolloProvider>


  );
}

export default App;

2 Answers 2

2

React.useContext<Context>(MovieDetailContext) expects a parameter of type <Context> but your passing in MovieDetailContext which is of type <Context | {}>

You should remove the empty object from the context type and either set it to undefined or the object with the values set to undefined

 export const MovieDetailContext = React.createContext<Context>(undefined);

Same issue with movieData when passing in the value for the Provider it's expecting MovieObject so you need set the type fro the state to a simple MOvieObject and pass in a MovieObject or undefined for initial value

const [movieData, setMovieData] = React.useState<MovieObject>(undefined)
Sign up to request clarification or add additional context in comments.

Comments

1

You problaly need to adapt the type of your useContext statement to match the type of your createContext statement:

// change from
useContext<Context>(MovieDetailContext)
// to
useContext<Context | {}>(MovieDetailContext)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.