Я изучаю реагировать и Typescript, Мне нужно передать объект интерфейса TypeScript от родительского к дочернему компоненту, если я удалю TypeScript и сделаю это в чистом React, это сработает.
Интерфейс TypeScript
export interface IUser {
id: number;
name: string;
username: string;
email: string;
}
Родитель.tsx
import { useEffect, useState } from "react";
import { IUser } from "./ApiInterface";
import Child from "./Child";
export default function App() {
const [users, setUsers] = useState<IUser[]>();
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then((res) => res.json())
.then((res) => setUsers(res as IUser[]));
}, []);
return <Child users = {users} />;
}
Ребенок.tsx
import { IUser } from "./ApiInterface";
const Child: React.FunctionComponent<IUser[]> = (users: IUser[]): JSX.Element => {
return (
<div>
{users.map((u, i) => (
<h1 key = {u.id}>{u.name}</h1>
))}
</div>
);
};
export default Child;
ошибка
ERROR in src/App.tsx:14:17
TS2322: Type '{ users: IUser[] | undefined; }' is not assignable to type 'IntrinsicAttributes & IUser[]'.
Property 'users' does not exist on type 'IntrinsicAttributes & IUser[]'.
12 | }, []);
13 |
> 14 | return <Child users = {users} />;
| ^^^^^
15 | }
16 |
🤔 А знаете ли вы, что...
JavaScript имеет множество библиотек и фреймворков, таких как jQuery, Angular, и Vue.js.
Вы используете неправильный тип для вашего дочернего компонента. Вы используете React.FC<IUser[]>
, что означает, что ваш дочерний компонент ожидает массив объектов IUser
в качестве реквизита, но вы передаете объект со свойством users
, которое содержит массив объектов IUser
.
Чтобы исправить это, вам нужно использовать правильный тип для вашего дочернего компонента и установить начальное значение для вашей переменной состояния users
.
Например:
// define correct type for child component
interface ChildProps {
users: IUser[];
}
const Child: React.FC<ChildProps> = ({ users }: ChildProps): JSX.Element => {
return (...);
};
// initialize state value
const [users, setUsers] = useState<IUser[]>([]);
Вы можете увидеть весь пример здесь: codeandbox.io
Вам не обязательно создавать новый интерфейс для каждого интерфейса, который вы хотите передать в качестве реквизита. Вы также можете указать тип вашего реквизита в строке, например @sai vineeth, предложенный в комментарии, или просто напрямую использовать существующий интерфейс.
Например:
const Child: React.FC<{ users: IUser[] }> = ({ users }: { users: IUser[] }): JSX.Element => { return (...); };
Но лучше создать интерфейс. Создание отдельного интерфейса для вашего реквизита может улучшить качество вашего кода, возможность повторного использования и согласованность.
В конечном счете, вы должны решить, что лучше всего подходит для вас и вашей ситуации, но я думаю, что это хорошая идея, когда это возможно, создавать отдельный интерфейс для ваших реквизитов.