【问题标题】:React with Typescript: Type missmatch使用 Typescript 做出反应:类型不匹配
【发布时间】:2019-09-03 03:04:27
【问题描述】:

开始使用带有 typescript 的 React 有一段时间了,但总是对类型和 React 元素的期望感到困惑。

就像在这种情况下(也sandbox here)我得到了 Todos 组件的以下错误

在具有更漂亮和 TSLint 设置的 VSCODE 中:类型 '(props: PropsWithChildren) => Element[]' 不可分配给类型 'FunctionComponent'。

在 Snadbox 中:类型 '(props: IProps) => void[]' 不可分配给类型 'FunctionComponent'。


    import { TodoStore } from "./stores/TodoStore";
    import { observable } from "mobx";
    interface IProps {
      todoStore: TodoStore;
    }
   // red underline at `TodoComp` with mentioned error message
    const TodosComp: React.FC<IProps> = props => {
      const { todos } = props.todoStore;
      return todos.map(todo => {
        <div key={todo.id}>
          <p>{todo.title}</p>
          <select />
        </div>;
      });
    };
    export default inject("todoStore")(observer(TodosComp));

待办事项的 Mobx 商店就像

import { decorate, observable, runInAction, action } from 'mobx';
export interface ITodo {userId: number; id: number; title: string; completed: boolean;
}
export class TodoStore {
  public todos: ITodo[];
  constructor() {
    this.todos = [];
    this.fetchTodos();
  }

  public async fetchTodos() {
    const response = await fetch('http://jsonplaceholder.typicode.com/todos');
    const todos: ITodo[] = await response.json();
    runInAction(() => {
      this.todos = todos;
    });
 }}
decorate<TodoStore>(TodoStore, { todos: observable, fetchTodos: action });

是 Mobx 的问题吗?如果类本身被用作组件中的类型? mobx 类需要单独的接口吗?

同样作为 Mobx 特定的问题,沙盒中正确实例化提供者商店类的方式是什么?

一般来说,如果有人知道一篇关于 React with typescript 如何管理 props 和 JSX 类型的好文章将不胜感激。

【问题讨论】:

    标签: reactjs typescript mobx-react react-tsx


    【解决方案1】:

    FunctionComponent 定义为

    interface FunctionComponent<P = {}> {
      (props: PropsWithChildren<P>, context?: any): ReactElement | null;
      ...
    

    ReactElement 在哪里

    interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
      type: T;
      props: P;
      key: Key | null;
    }
    

    通过查看这些定义,您可以看出您无法从React.FC 返回数组。解决方案是将您的返回值包装在反应片段中,例如

    return (
      <>
        {todos.map(todo => {
          <div key={todo.id}>
            <p>{todo.title}</p>
            <select />
          </div>;
        })}
      </>
    );
    

    【讨论】:

      【解决方案2】:

      函数应该返回一个 JSX.Element 并且你需要传递一个 div 或一个 Fragment,这应该可以工作。

      const Todos: React.FC<IProps> = (props: IProps): JSX.Element => {
        const { todos } = props.todoStore;
        return (<React.Fragment>
          {todos.map(todo => {
            <div key={todo.id}>
              <p>{todo.title}</p>
              <select />
            </div>;
          })}
        </React.Fragment>);
      };
      

      【讨论】:

      • 谢谢,这是问题所在。我只想解决 Mobx 问题。但以防万一我的方法对于创建新的 mobx 状态即时正确?
      猜你喜欢
      • 2019-12-04
      • 2018-10-02
      • 2019-10-19
      • 2018-05-15
      • 2018-12-11
      • 2021-12-21
      • 2020-08-10
      • 2019-01-10
      • 2014-10-18
      相关资源
      最近更新 更多