有一段时间开始将React与Typescript一起使用,但总是与类型和React元素的期望混淆。
像在这种情况下一样(也sandbox here),我得到了Todos组件的以下错误
在具有更漂亮和TSLint设置的VSCODE中:类型'(props:PropsWithChildren)=>元素[]'不能分配给'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的文章有很好的了解,那么如何管理道具和JSX类型将不胜感激。
答案 0 :(得分:1)
函数应该返回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>);
};
答案 1 :(得分: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
返回数组。解决方案是将您的返回值包装在类似React的片段中
return (
<>
{todos.map(todo => {
<div key={todo.id}>
<p>{todo.title}</p>
<select />
</div>;
})}
</>
);