'Why does the useQuery hook in react-query force me to check if the returned data is not undefined
I'm experimenting with react-query as a replacement for my custom logic when loading data from a server in a react application.
What I cannot seem to understand is why (at least) the TypeScript typing suggests that the data property the object returned by useQuery can be undefined?
If I remove the if (!query.data) {return <span>No data found</span>;} guard in the following example, TypeScript complains that query.data can be undefined.
When running the example it does not seem to be undefined but (at least) the TypeScript definition assumes that it might be.
Is there any documentation that I've missed explaining why data might be undefined?
Why does the typing suggest that data can be undefined?
Is there a situation where data can be undefined at runtime?
Could should not the API itself make this check and generate an error if data is really undefined?
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>
);
};
Solution 1:[1]
why is this check needed?
because the state machine internally has 4 main states:
- loading
- error
- success
- idle
types are narrowed depending on it, but in your example, you only eliminate loading and error from the union. What remains is success or idle. If you eliminate idle as well, only success remains and the check is unnecessary.
You might want to take a look at react-query v4 though. We have removed the idle state from the main state machine there, which would make the extra check in your example unnecessary.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | TkDodo |
