[英]Typescript error got undefined with useState hook
Im new to graphql so I decided to follow this guide .我是 graphql 的新手,所以我决定遵循本指南。
However I got an error when querying (step 7) :但是在查询时出现错误(第 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 | }
Here is the component:这是组件:
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
However it works when I use但是它在我使用时有效
data.allUsers.nodes
Like this :像这样 :
{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 />
)}
And of course I've removed setUsers
in the useEffect()
hooks.当然,我已经删除
setUsers
在useEffect()
挂钩。
I notice that I had to set strict to false in my .tsconfig.json
file.我注意到我必须在我的
.tsconfig.json
文件中将 strict 设置为 false。
I would like to know why I m not able to use the setUsers hooks?我想知道为什么我不能使用 setUsers 钩子? Why I got that error and how to solve it?
为什么我得到那个错误以及如何解决它?
Thank you!谢谢!
Possibly:可能:
const [users, setUsers] = useState()
should be:应该:
const [users, setUsers] = useState([])
When you call useState
without setting an initial value, typescript doesn't know what value that state is expected to be.当您
useState
不设置初始值的情况下调用useState
,打字稿不知道该状态应该是什么值。 You need to declare it explicitly by setting the generic.您需要通过设置泛型来明确声明它。
const [users, setUsers] = useState<User[]>();
Now typescript knows that our state can only be an array of User
objects or undefined
.现在打字稿知道我们的状态只能是一个
User
对象或undefined
的数组。
If we want to exclude the possibility of undefined
, we can initialize it with an empty array []
.如果我们想排除
undefined
的可能性,我们可以用一个空数组[]
来初始化它。 We still need to provide the generic to specify what type of elements are in the array.我们仍然需要提供泛型来指定数组中的元素类型。 But now
users
is always an array of zero or more User
objects.但是现在
users
总是零个或多个User
对象的数组。
const [users, setUsers] = useState<User[]>([]);
So of your runtime checks become unnecessary when we have proper typings.因此,当我们有正确的类型时,您的运行时检查就变得不必要了。 With the
useState
line above, your return
becomes:使用上面的
useState
行,您的return
变为:
return (
<>
<h2>Hello users,</h2>
{users.map((user, index) => (
<p key={`user_${index}`}>
{user.name}{' '}
</p>
))}
</>
)
It's ok to map
on empty array, so we don't need to check anything.在空数组上
map
是可以的,所以我们不需要检查任何东西。 We also don't need to declare the types for user
and index
because they are already known based on the type of the users
array.我们也不需要声明
user
和index
的类型,因为它们已经基于users
数组的类型已知。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.