使用useState挂钩未定义打字稿错误

时间:2020-11-01 20:47:25

标签: reactjs typescript graphql react-apollo react-apollo-hooks

我是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 />
      )}

当然,我已经删除了setUsers钩子中的useEffect()

我注意到我必须在.tsconfig.json文件中将strict设置为false。

我想知道为什么我不能使用setUsers挂钩?为什么我会收到该错误以及如何解决?

谢谢!

2 个答案:

答案 0 :(得分:1)

可能:

const [users, setUsers] = useState()

应为:

const [users, setUsers] = useState([])

答案 1 :(得分:1)

在不设置初始值的情况下调用useState时,打字稿不知道该状态应为哪个值。您需要通过设置泛型来明确声明它。

const [users, setUsers] = useState<User[]>();

现在打字稿知道我们的状态只能是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是可以的,因此我们不需要检查任何内容。我们也不需要声明userindex的类型,因为已经基于users数组的类型知道它们了。