为什么 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
状态,这将使您的示例中的额外检查变得不必要。
在 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
状态,这将使您的示例中的额外检查变得不必要。