有条件地调用useQuery会导致生成失败



我有一个用例,在UI中,我显示与用户相关联的所有todo的列表。有一个切换按钮,切换它,只显示同一用户的completedtodo列表。我正在调用react hookuseQuery,但根据切换按钮状态有条件地。以下是代码:

import TodoItems from './TodoItems';
import { LIST_TODOS_BY_USERNAME, LIST_TODOS_BY_STATUS } from '../graphql/queries';
import { useQuery } from '@apollo/react-hooks';
type TodoListProps = {
username: string;
showCompleted: boolean;
};
const TodoList:FC<TodoListProps> = ({ username, showCompleted }) => {
const { loading, error, data } = !showCompleted
? useQuery(LIST_TODOS_BY_USERNAME, { variables: { username }, pollInterval: 500 })
: useQuery(LIST_TODOS_BY_STATUS, { variables: { username, status: 'COMPLETED' }, pollInterval: 500 });
if (error) {
return (
<div>
<p>{`Error! ${error}`}</p>
</div>
);
}
return (
<div className="todoapp">
<div>
<header className="header">
<div className="imagetool">
<img
alt={username}
src={`https://something.com/?uid=${username}`}
/>
</div>
<H1>
{username}
&rsquo;s todos
</H1>
<div className="todo-list-container">
<Row gridGap={32} justifyContent="center" padding={8}>
<View>
{loading ? (
<Col alignItems="start" gridGap={16}>
<Spinner size={SpinnerSize.Small} />
</Col>
) : (
<TodoItems todoListItems={!showCompleted ? data.getTodosByUserName : data.getTodosByStatus} />
)}
</View>
</Row>
</div>
</header>
</div>
</div>
);
};
export default TodoList;

然而,这很有效,但在构建过程中,由于linting开始发挥作用,它失败了,并出现错误:

17:7错误React Hook;useQuery"被有条件地调用。React钩子必须在每个组件中以完全相同的顺序调用,呈现React钩子/钩子规则

如何在不禁用lint规则的情况下解决问题?

任何建议都将不胜感激!

在React中,钩子需要总是被调用——因此它们应该而不是只在有时被调用(=有条件地(。这甚至适用于使用相同钩子函数的钩子(在您的情况下为useQuery()(。要在每次渲染迭代的上调用非常相同的useQuery(),请使用一个钩子;因此

更改此

const { loading, error, data } = !showCompleted
? useQuery(LIST_TODOS_BY_USERNAME, { variables: { username }, pollInterval: 500 })
: useQuery(LIST_TODOS_BY_STATUS, { variables: { username, status: 'COMPLETED' }, pollInterval: 500 });

到此:

const { loading, error, data } = useQuery(
!showCompleted ? LIST_TODOS_BY_USERNAME : LIST_TODOS_BY_STATUS,
{
variables: !showCompleted
? { username }
: { username, status: 'COMPLETED' },
pollInterval: 500,
}
)

不要有条件地使用useQuery。您有两个选项,要么将查询作为道具的值,要么将该查询的名称存储在组件的状态中,并根据需要进行更改。

最新更新