reactjs - React และ TypeScript—ประเภทไหนสำหรับการตอบสนองของ Axios?
ฉันกำลังพยายามแสดงรายการผู้ใช้ง่าย ๆ จาก API ซึ่งส่งค่าดังนี้:
[{"UserID":2,"FirstName":"User2"},{"UserID":1,"FirstName":"User1"}]
ฉันไม่เข้าใจอย่างเต็มที่ว่าต้องจัดการกับการตอบสนองของ Axios พร้อมชนิดข้อมูลอย่างไร ข้อผิดพลาดของ TypeScript คือ
ประเภท ' {} | { id: number; firstName: string; } ' ไม่สามารถกำหนดค่าให้กับประเภท ' IntrinsicAttributes & UserListProps & { children?: ReactNode; } ' ได้.
คุณสมบัติ 'items' หายไปในประเภท '{}' แต่จำเป็นในประเภท 'UserListProps'
จากองค์ประกอบ <UserList /> ในไฟล์ Users.tsx ด้านล่าง อินเทอร์เฟซ User ของผมผิดหรือไม่?
import React, {useEffect, useState, Fragment } from 'react';
import UserList from './UserList';
import axios, {AxiosResponse} from 'axios';
interface User {
id: number;
firstName: string;
}
const Users: React.FC = (props) => {
const [users, setUserList] = useState<User>();
useEffect(() => {
// Use [] as second argument in useEffect for not rendering each time
axios.get('http://localhost:8080/admin/users')
.then((response: AxiosResponse) => {
console.log(response.data);
setUserList( response.data );
});
}, []);
return (
<Fragment>
<UserList {...users} />
</Fragment>
);
};
export default Users;
ด้านล่างนี้คื่อ UserList.tsx ของฉัน
import React, {Fragment } from 'react';
interface UserListProps {
items: {id: number, firstName: string}[];
};
const UserList: React.FC<UserListProps> = (props) => {
return (
<Fragment>
<ul>
{props.items.map(user => (
<li key={user.id}>
<span>{user.firstName}</span>
{/* not call delete function, just point to it
// set this to null in bind() */}
</li>
))}
</ul>
</Fragment>
);
};
export default UserList;
คำตอบ #1
มีเมธอดทั่วไป get ที่ถูกกำหนดไว้ใน axios/index.d.ts
get<T = never, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig<T>): Promise<R>;
ตัวอย่าง
interface User {
id: number;
firstName: string;
}
axios.get<User[]>('http://localhost:8080/admin/users')
.then(response => {
console.log(response.data);
setUserList( response.data );
});
ฉันคิดว่าคุณกำลังส่งรายการไปยังคอมโพเนนต์ลูกในทางที่ผิด
const [users, setUserList] = useState<User[]>([]);
<UserList items={users} />
interface UserListProps {
items: User[];
};
const UserList: React.FC<UserListProps> = ({items}) => {
return (
<Fragment>
<ul>
{items.map(user => (
<li key={user.id}>
<span>{user.firstName}</span>
</li>
))}
</ul>
</Fragment>
);
};
คำตอบ #2
คุณต้องระบุอาร์กิวเมนต์ประเภทเมื่อเรียกใช้งาน axios.get หากคุณไม่ต้องการให้ Axios ประเมินประเภทสำหรับค่าของ response เป็น any
และคุณกำลังส่งอาร์กิวเมนต์ประเภทไม่ถูกต้องเมื่อคุณ useState เพื่อสร้างอาร์เรย์ของผู้ใช้
วิธีที่ถูกต้อง
interface User {
id: number;
firstName: string;
}
// Initialized as an empty array
const [users, setUserList] = useState<User[]>([]); // 'users' will be an array of users
ตัวอย่างเช่น,
import React, {useEffect, useState, Fragment } from 'react';
import UserList from './UserList';
import axios from 'axios';
interface User {
id: number;
firstName: string;
}
// You can export the type TUserList to use as -
// props type in your `UserList` component
export type TUserList = User[]
const Users: React.FC = (props) => {
// You can also use User[] as a type argument
const [users, setUserList] = useState<TUserList>();
useEffect(() => {
// Use [] as a second argument in useEffect for not rendering each time
axios.get<TUserList>('http://localhost:8080/admin/users')
.then((response) => {
console.log(response.data);
setUserList(response.data);
});
}, []);
return (
<Fragment>
<UserList {...users} />
</Fragment>
);
};
export default Users;
หากคุณเลือกที่จะส่งออกชนิด type TUserList=User[] คุณสามารถใช้มันในคอมโพเนนต์ UserList ของคุณเป็นชนิดของ props ได้ ตัวอย่างเช่น,
import React, {Fragment } from 'react';
import { TUserList } from './Users';
interface UserListProps {
items: TUserList // Don't have to redeclare the object again
};
const UserList: React.FC<UserListProps> = (props) => {
return (
<Fragment>
<ul>
{props.items.map(user => (
<li key={user.id}>
<span>{user.firstName}</span>
{ /* Do not call the delete function. Just point
to it. Set this to null in bind(). */}
</li>
))}
</ul>
</Fragment>
);
};
export default UserList;
