【问题标题】:Typescript and Context API打字稿和上下文 API
【发布时间】:2020-08-31 13:08:35
【问题描述】:

我正在尝试在应用程序中同时实现 Typescript 和 Context API。我面临着将deleteMovie和addMovie的功能实现到MovieContext.Provider的value prop中的问题。

这是我收到的错误:

Type '{ movies: MovieAttribute[]; deleteMovie: (id: number) => void; addMovie: (id: number, title: string) => void; }' is not assignable to type '{ movies: { id: number; title: string; }[]; }'.
  Object literal may only specify known properties, and 'deleteMovie' does not exist in type '{ movies: { id: number; title: string; }[]; }'.ts(2322)
index.d.ts(337, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps<{ movies: { id: number; title: string; }[]; }>'

根据我对错误的理解,我是否正确地说我尚未声明我的 Provider 的值不包含“函数类型”。如果是这样,我该如何修改这个问题?

MovieContext.tsx

import React, { createContext, useReducer } from 'react';
import MovieReducer from '../reducers/MovieReducer';

const initialState = { 
    movies: [
        {
            id: 1,
            title: "King Kong"
        },
        {
            id: 2,
            title: "Spiderman"
        }
    ]
};

export const MovieContext = createContext(initialState);

export const MovieProvider = (props: { children: React.ReactNode }) => {
    const [state, dispatch] = useReducer(MovieReducer, initialState);

    // Actions
    function deleteMovie(id: number): void {
        dispatch({
            type: 'DELETE_MOVIE',
            payload: { id, title: 'nil' }
        })
    }

    function addMovie(id: number, title: string): void {
        dispatch({
            type: 'ADD_MOVIE',
            payload: { id, title }
        })
    }

    return (
        <MovieContext.Provider value={{
            movies: state.movies,
            deleteMovie,
            addMovie
        }}>
            {props.children}
        </MovieContext.Provider>
    )
}

如果代码的任何部分也可以改进,请告诉我!我最近才开始研究 Typescript,而今天刚刚开始研究 Context。

【问题讨论】:

    标签: reactjs typescript react-hooks react-context


    【解决方案1】:

    上下文的类型取决于它的声明。如果在上面树中没有上下文提供程序的情况下检索上下文,则在调用 createContext 时需要指定类型以及合理的默认值:

    // You could move the anonymous type between <> to an interface 
    export const MovieContext = createContext<{
      movies: Movie[],
      deleteMovie(id: number): void;
      addMovie(id: number, title: string): void;
    }>({
      ...initialState,
      addMovie: () => {},
      deleteMovie: () => {}
    });
    

    Playground Link

    【讨论】:

    • 谢谢。我可以澄清addMovie: () =&gt; {} 声明 addMovie 是一个函数吗?如果是这样,还有其他方法可以在 typescript 中声明函数吗?
    • @MongChangHsi 只是一个空函数,你也可以使用addMovie() {}。这个空函数实际上不应该被调用,因为如果你有一个 MovieContext.Provider 作为父级,则永远不会使用上下文的默认值。 addMovies 的替代值将是 null!(在不应为 null 的内容中强制为 null)或 addMovie: () =&gt; { throw new Error("No context for movies exists")}。如果您忘记添加提供程序,这两者都会导致运行时错误(这实际上可能是一件好事)。上面的空函数只会默默地不做任何事情。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2020-09-14
    • 2021-07-20
    • 2020-12-19
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    相关资源
    最近更新 更多