打字稿错误未使用 useState 钩子定义
Posted
技术标签:
【中文标题】打字稿错误未使用 useState 钩子定义【英文标题】:Typescript error got undefined with useState hook 【发布时间】:2021-02-14 14:17:41 【问题描述】:我是 graphql 的新手,所以我决定关注这个 guide。
但是查询时出现错误(第 7 步):
Argument of type '( __typename?: "User"; & Pick<User, "email" | "id" | "name" | "createdAt">)[]' is not assignable to parameter of type '(prevState: undefined) => undefined'.
Type '( __typename?: "User"; & Pick<User, "email" | "id" | "name" | "createdAt">)[]' provides no match for the signature '(prevState: undefined): undefined'. TS2345
37 | if (data && data.allUsers)
38 | if (data && data.allUsers && data.allUsers.nodes)
> 39 | setUsers(data.allUsers.nodes);
| ^
40 |
41 |
42 |
这是组件:
import React, useState, useEffect from 'react'
import useGetUsers from '../utils/services'
import User from '../generated/graphql'
const Users: React.FC = () =>
const [users, setUsers] = useState()
const data, error, loading = useGetUsers()
useEffect(() =>
if (data)
if (data && data.allUsers && data.allUsers.nodes)
setUsers(data.allUsers.nodes)
if (error)
console.log(error)
if (loading)
console.log(loading)
, [data, error, loading])
return (
<>
<h2>Hello users,</h2>
users &&
users.length > 0 &&
users.map((user: User, index: number) => (
<p key=`user_$index`>
user.name' '
</p>
))
</>
)
export default Users
但是当我使用它时它会起作用
data.allUsers.nodes
像这样:
data && data.allUsers ? (
data.allUsers.nodes &&
data.allUsers.nodes.length > 0 &&
data.allUsers.nodes.map((user: User, index: number) => (
<p key=`user_$index`>user.name</p>
))
) : (
<React.Fragment />
)
当然,我已经删除了 useEffect()
挂钩中的 setUsers
。
我注意到我必须在 .tsconfig.json
文件中将 strict 设置为 false。
我想知道为什么我不能使用 setUsers 钩子?为什么会出现该错误以及如何解决?
谢谢!
【问题讨论】:
不需要在本地复制数据......只需使用const users = loading ? [] : data.allUsers.nodes;
或const users = data ? [] : data.allUsers.nodes;
before return
【参考方案1】:
可能:
const [users, setUsers] = useState()
应该是:
const [users, setUsers] = useState([])
【讨论】:
如果未指定类型,则将空数组推断为never[]
。【参考方案2】:
当您在没有设置初始值的情况下调用useState
时,打字稿不知道该状态应该是什么值。您需要通过设置泛型来显式声明它。
const [users, setUsers] = useState<User[]>();
现在 typescript 知道我们的状态只能是 User
对象或 undefined
的数组。
如果我们想排除undefined
的可能性,我们可以用一个空数组[]
来初始化它。我们仍然需要提供泛型来指定数组中的元素类型。但是现在users
始终是一个包含零个或多个User
对象的数组。
const [users, setUsers] = useState<User[]>([]);
所以当我们有正确的类型时,你的运行时检查就变得不必要了。使用上面的useState
行,您的return
变为:
return (
<>
<h2>Hello users,</h2>
users.map((user, index) => (
<p key=`user_$index`>
user.name' '
</p>
))
</>
)
map
在空数组上是可以的,所以我们不需要检查任何东西。我们也不需要声明user
和index
的类型,因为它们是基于users
数组的类型已知的。
【讨论】:
以上是关于打字稿错误未使用 useState 钩子定义的主要内容,如果未能解决你的问题,请参考以下文章
使用反应成帧器类型'()=> void'的打字稿错误不可分配给类型'未定义'