Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

createContext doesn't accept defaultValue

I'm trying to build a context by using createContext from the react API:

import React, { useState, createContext } from 'react';

export const MovieContext =  createContext();

export const MovieProvider = (props) => {
  const [movies, setMovies] = useState(
    [
      {
        original_title: 'name of movie',
        poster_path: 'path_to_poster',
        id: 1
      }
    ]
  );
  return (
    <MovieContext.Provider value={[movies, setMovies]}>
      {props.children}
    </MovieContext.Provider>
  );
}

export default MovieProvider;

The createContext() function shows this error:

Expected 1 arguments, but got 0.ts(2554) index.d.ts(385, 9): An argument for 'defaultValue' was not provided.

If I make it a string, and pass a string as value the app builds:

export const MovieContext =  createContext('');

<MovieContext.Provider value={''}>
  {props.children}
</MovieContext.Provider>

What kind of value do I add as a createContext() parameter to make it work with the useState hook? I'm following this guys tutorial and he does it in JS but I'm building my app in TS so it's a bit more strict.

like image 671
Peter Boomsma Avatar asked Jul 31 '20 14:07

Peter Boomsma


People also ask

What is default value of createContext?

createContext(defaultValue); Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching Provider above it in the tree.

How many arguments does React createContext () take?

const Context = createContext('Default Value'); The factory function accepts one optional argument: the default value.

What is a React context?

What is React context? React context allows us to pass down and use (consume) data in whatever component we need in our React app without using props. In other words, React context allows us to share data (state) across our components more easily.


1 Answers

These are the Typescript types, they are described here. There is a comment in the code why this argument should be required, although the documentation doesn't say it is required.

function createContext<T>(
    // If you thought this should be optional, see
    // https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24509#issuecomment-382213106
    defaultValue: T,
): Context<T>;

In your case will correctly set the default parameter like

type IMovie = {
    original_title: string;
    poster_path: string;
    id: number;
};

type IMovieContext = [IMovie[], React.Dispatch<React.SetStateAction<IMovie[]>>];

export const MovieContext = createContext<IMovieContext>([[], () => null]);

export const MovieProvider = props => {
    const [movies, setMovies] = useState<IMovie[]>([
        {
            original_title: 'name of movie',
            poster_path: 'path_to_poster',
            id: 1,
        },
    ]);
    return <MovieContext.Provider value={[movies, setMovies]}>{props.children}</MovieContext.Provider>;
};
like image 98
Nikita Madeev Avatar answered Sep 18 '22 12:09

Nikita Madeev