为什么 react-query 中的 useQuery 钩子强制我检查返回的数据是否未定义

Why does the useQuery hook in react-query force me to check if the returned data is not undefined

在 React 应用程序中从服务器加载数据时,我正在尝试使用 React-query 来替代我的自定义逻辑。

我似乎无法理解的是,为什么(至少)TypeScript 类型表明 data 属性 useQuery 返回的对象可以是 undefined

如果我在下面的示例中删除 if (!query.data) {return <span>No data found</span>;} 守卫,TypeScript 会抱怨 query.data 可以是 undefined.

当 运行 示例时,它似乎没有未定义,但(至少)TypeScript 定义假定它可能是未定义的。

是否有任何我遗漏的文档来解释为什么 data 可能未定义? 为什么输入提示 data 可以未定义? 是否存在 data 可以在运行时未定义的情况? 如果数据确实未定义,API 本身不应该进行此检查并生成错误吗?

import React from 'react';
import {useQuery} from 'react-query';

type TodoType = {
    id: number,
    title: string,
};

const todos: TodoType[] = [
    {
        id: 1,
        title: 'foo',
    },
    {
        id: 2,
        title: 'bar',
    },
];

const getTodos = (): Promise<TodoType[]> => new Promise(resolve => setTimeout(() => resolve(todos), 250));

export const Todos = (): JSX.Element => {
    const query = useQuery('todos', getTodos);
  
    if (query.isLoading) {
        return <span>Loading...</span>;
    }
  
    if (query.isError) {
        const error = query.error instanceof Error ? query.error.message : 'Error';
        return <span>{error}</span>;
    }

    // why is this check needed?  
    if (!query.data) {
        return <span>No data found</span>;
    }

    return (
        <div>
            <ul>
                {query.data.map((todo) => (<li key={todo.id}>{todo.title}</li>))}
            </ul>
        </div>
    );
};

why is this check needed?

因为状态机内部有4个主要状态:

  • 加载中
  • 错误
  • 成功
  • 空闲

类型根据它缩小,但在您的示例中,您只消除了联合的加载和错误。剩下的就是成功或闲置。如果把idle也去掉,就只剩下成功了,就不用检查了。

不过您可能想看看 react-query v4。我们已经从那里的主状态机中删除了 idle 状态,这将使您的示例中的额外检查变得不必要。