简体   繁体   English

React Typescript 如何设置状态

[英]React Typescript how to setState

I am trying to learn typescript with react and I am pretty confused right now, how will I setState of an interface?我正在尝试使用 react 学习打字稿,现在我很困惑,我将如何设置接口的状态? My code example:我的代码示例:

interface Props {
    children: ReactNode | ReactNode[];
}

export interface IMovie {
    title: string;
    video: boolean;
    poster_path: string;
}

export const MoviesContext = createContext<IMovie[] | undefined>([]);

export const MoviesProvider = ({ children }: Props): JSX.Element => {
    const [movies, setMovies] = useState<IMovie[]>();

    return (
            <MoviesContext.Provider value={[movies, setMovies]}>
                {children}
            </MoviesContext.Provider>
    );
};

The error I get is "Type (ΙΜovie[] | Dispatch> | undefined>> is not assignable to type IMovie[]"我得到的错误是“类型(ΙΜovie[] | Dispatch> | undefined>> 不能分配给类型 IMovie[]”

any other suggestions on what to change on my code welcomed.欢迎任何其他关于更改我的代码的建议。 :) :)

The issue here is the value type that your context is defined with is IMovie , where as the type being passed to your context during rendering is actually an array: [movies, setMovies] .这里的问题是您的上下文定义的值类型是IMovie ,其中在渲染期间传递给您的上下文的类型实际上是一个数组: [movies, setMovies]

One solution would be to define and use a prop interface with your provider, that carries both the movies state as well as the setter for movies like this:一种解决方案是与您的提供者一起定义和使用 prop 接口,该接口包含movies状态以及电影的设置器,如下所示:

export interface IMovieProviderProps {
    movies? : IMovie,
    setMovies : (movies:IMovie) => void,
}

This IMovieProviderProps interface would then be used to define the shape of your context value, which would provide the means for accessing the movies state as well as updating it, from outside the provider:这个IMovieProviderProps接口将用于定义上下文值的形状,这将提供从提供者外部访问movies状态以及更新它的方法:

/* Define context with new provider props */
export const MoviesContext = createContext<IMovieProviderProps>(null);

export const MoviesProvider = ({ children }: Props): JSX.Element => {
    const [movies, setMovies] = useState<IMovie>();

    /* Define provider value. Can be done inline, but I've defined
    it here for clarity */
    const providerValue : IMovieProviderProps = {
        movies,
        setMovies
    }

    /* Pass providerValue to provider */
    return (<MoviesContext.Provider value={providerValue}>
        {children}
    </MoviesContext.Provider>);
};

/* Define a hook for this provider, that allows the provided value
to be consumed */
export const useMovies = () => useContext(MoviesContext);

The useMovies hook allows the provider value to be accessed from elsewhere in your project, and can be used like this: useMovies钩子允许从项目中的其他地方访问提供者值,并且可以像这样使用:

const ExampleComponent = () => {

     /* Imported useMovies hook defined with provider above, and
     extract the movies state, and movies setter base on the shape
     of IMovieProviderProps */
     const { movies, setMovies } = useMovies();

     return <>
     {JSON.stringify(movies)}
     <button onClick={() => setMovies(null)}>Set Movies</button>
     </>
}

A key thing to note now is that the context now exposes an object value with the shape of IMovieProviderProps rather than an array value (as your code may have been expecting).现在需要注意的一个关键点是,上下文现在公开了一个具有IMovieProviderProps形状的对象值,而不是一个数组值(正如您的代码所期望的那样)。

Hope that helps!希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM