React 和 Typescript,Axios 响应的类型?

G. *_*lly 28 typescript reactjs axios

我试图从返回这个的 API 中呈现一个简单的用户列表:

[{"UserID":2,"FirstName":"User2"},{"UserID":1,"FirstName":"User1"}]
Run Code Online (Sandbox Code Playgroud)

我不完全理解如何处理带有类型的 Axios 响应。打字稿错误是

Type '{} | { id: number; firstName: string; }' is not assignable to type 'IntrinsicAttributes & UserListProps & { children?: ReactNode; }'.
Property 'items' is missing in type '{}' but required in type 'UserListProps'.
Run Code Online (Sandbox Code Playgroud)

来自下面文件中的<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;
Run Code Online (Sandbox Code Playgroud)

下面是我的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;
Run Code Online (Sandbox Code Playgroud)

Józ*_*cki 32

中定义的通用get方法Axios公司/ index.d.ts

get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
Run Code Online (Sandbox Code Playgroud)

例子

interface User {
    id: number;
    firstName: string;
}


axios.get<User[]>('http://localhost:8080/admin/users')
        .then(response => {
            console.log(response.data);
            setUserList( response.data );
        });
Run Code Online (Sandbox Code Playgroud)

- 编辑

我认为您将列表以错误的方式传递给子组件。

const [users, setUserList] = useState<User[]>([]);
Run Code Online (Sandbox Code Playgroud)
<UserList items={users} />
Run Code Online (Sandbox Code Playgroud)
<UserList items={users} />
Run Code Online (Sandbox Code Playgroud)
interface UserListProps {
    items: User[];
};
Run Code Online (Sandbox Code Playgroud)

  • 更新了答案。我一开始以为你只是得到单个对象,但这实际上是一个数组。只需在少数地方加上“[]”括号即可 (2认同)
  • 您必须使用空数组初始化“useState([])”。否则你必须扩展类型 `useState&lt;User[] | undefined&gt;()` 添加检查子组件中变量是否未定义并对其执行某些操作 (2认同)

sub*_*tra 6

axios.get如果您不希望 axios 将值的类型推断为 any,则需要在调用时提供类型参数response

并且useState在创建用户数组时传递了不正确的类型参数。

正确的方法

interface User {
  id: number;
  firstName: string;
}

// initialized as an empty array
const [users, setUserList] = useState<User[]>([]); // users will be an array of users
Run Code Online (Sandbox Code Playgroud)

例如,

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 type argument
    const [users, setUserList] = useState<TUserList>();

    useEffect(() => {
        // Use [] as 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;
Run Code Online (Sandbox Code Playgroud)

如果你选择导出类型,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>
                    {/* not call delete function, just point to it
                    // set this to null in bind() */}
                </li>
            ))}
            </ul>
        </Fragment>
    );
};

export default UserList;
Run Code Online (Sandbox Code Playgroud)