React 和 Typescript,Axios 响应的类型都有哪些?
Posted
技术标签:
【中文标题】React 和 Typescript,Axios 响应的类型都有哪些?【英文标题】:React and Typescript, which types for Axios response?React 和 Typescript,Axios 响应的类型有哪些? 【发布时间】:2020-09-24 19:06:22 【问题描述】:我正在尝试从返回以下内容的 API 中呈现一个简单的用户列表:
["UserID":2,"FirstName":"User2","UserID":1,"FirstName":"User1"]
我不完全了解如何处理带有类型的 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'.
来自下面Users.tsx
文件中的<UserList />
元素。我的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】:有generic get
method defined in 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>
);
;
【讨论】:
谢谢,所以我应该使用axios.get<User>
而不是useState<User>()
?如果我尝试这样做,Typescript 会抱怨 useState()
未定义。
更新了答案。起初我以为你只是得到一个对象,但这实际上是一个数组。只需将[]
括号放在几个地方
我认为现在唯一缺少的部分是我如何初始化useState()
。我明白了:Argument of type 'User[]' is not assignable to parameter of type 'SetStateAction<undefined>'. Type 'User[]' provides no match for the signature '(prevState: undefined): undefined'.ts(2345)
你必须用空数组初始化useState([])
。否则,您必须扩展类型 useState<User[] | undefined>()
添加检查变量是否在子组件中未定义并对其进行处理【参考方案2】:
如果您不希望 axios 推断值 response
的类型,则需要在调用 axios.get
时提供类型参数。
当您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 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;
如果您选择导出类型type TUserList = User[]
,您可以在UserList
组件中使用它作为道具类型。例如,
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;
【讨论】:
关于导出TUserList
类型非常好,非常感谢您的出色回答:)
我很高兴它有帮助。以上是关于React 和 Typescript,Axios 响应的类型都有哪些?的主要内容,如果未能解决你的问题,请参考以下文章
React-query 和 Typescript - 如何正确输入突变结果?
react: typescript system params method optimize