使用 useState 钩子未定义打字稿错误
Typescript error got undefined with useState hook
我是 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, setUsers] = useState()
应该是:
const [users, setUsers] = useState([])
当您在未设置初始值的情况下调用 useState
时,typescript 不知道该状态的预期值。您需要通过设置泛型来显式声明它。
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
数组的类型已知。
我是 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, setUsers] = useState()
应该是:
const [users, setUsers] = useState([])
当您在未设置初始值的情况下调用 useState
时,typescript 不知道该状态的预期值。您需要通过设置泛型来显式声明它。
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
数组的类型已知。