有条件地调用 useQuery 会导致构建失败
Posted
技术标签:
【中文标题】有条件地调用 useQuery 会导致构建失败【英文标题】:Calling useQuery conditionally results into build failures 【发布时间】:2020-11-15 19:04:09 【问题描述】:我有一个用例,我在 UI 中显示与用户关联的所有待办事项列表。有一个切换按钮,切换它,仅显示同一用户的 completed
待办事项列表。我正在调用 react hook useQuery
但 有条件 基于切换按钮状态。下面是代码:
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
’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 Hooks 必须在每个组件渲染中以完全相同的顺序调用 react-hooks/rules-of-hooks
如何在不禁用 lint 规则的情况下解决问题?
任何指针表示赞赏!
【问题讨论】:
【参考方案1】:在 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,
)
【讨论】:
【参考方案2】:不要有条件地使用 useQuery。您有两种选择,要么将查询作为 prop 的值获取,要么将查询的名称存储在组件的状态中并根据需要进行更改。
【讨论】:
以上是关于有条件地调用 useQuery 会导致构建失败的主要内容,如果未能解决你的问题,请参考以下文章
如何在 react/apollo 中调用条件 useQuery 钩子
Apollo-client 有条件地同时运行 useLazyQuery 和 useQuery - 最好的方法是啥?