1

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

就像在这种情况下(这里也是沙箱)我得到了 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));

Todos 的 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 如何管理道具和 JSX 类型的好文章将不胜感激。

4

2 回答 2

3

函数应该返回一个 JSX.Element 并且您需要传递一个 div 或一个片段,这应该可以。

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>);
};
于 2019-04-12T11:42:46.993 回答
3

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>;
    })}
  </>
);
于 2019-04-12T11:44:10.520 回答