its a while started using React with typescript but always getting confused with types and what React element expects.
like in this scenario (Also sandbox here) I get the follwing error for Todos Component
in VSCODE with prettier and TSLint setup: Type '(props: PropsWithChildren) => Element[]' is not assignable to type 'FunctionComponent'.
in Snadbox: Type '(props: IProps) => void[]' is not assignable to type '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));
The Mobx store for todos is like
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 });
Is the problem from Mobx and if the class itself is used as a type in the component? does mobx classes need a separate interface?
Also as a Mobx specific question is the way in sandbox correct to instantiate the store class at provider?
in general, if somebody knows a good article about React with typescript how to manage props and JSX types would be appreciated.
Function should return a JSX.Element and you need to pass a div or a Fragment, this should works.
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>);
};