Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有条件地调用useQuery会导致生成失败_Javascript_Reactjs_Graphql_React Hooks - Fatal编程技术网

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

Javascript 有条件地调用useQuery会导致生成失败,javascript,reactjs,graphql,react-hooks,Javascript,Reactjs,Graphql,React Hooks,我有一个用例,在UI中我显示与用户相关的所有TODO的列表。有一个切换按钮,用于切换,仅显示同一用户的已完成的待办事项列表。我正在调用react hookuseQuery,但根据切换按钮状态有条件地调用。代码如下: import TodoItems from './TodoItems'; import { LIST_TODOS_BY_USERNAME, LIST_TODOS_BY_STATUS } from '../graphql/queries'; import { useQuery } fr

我有一个用例,在UI中我显示与用户相关的所有TODO的列表。有一个切换按钮,用于切换,仅显示同一用户的
已完成的
待办事项列表。我正在调用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}
            &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;
从“/TodoItems”导入TodoItems;
从“../graphql/querys”导入{LIST_TODOS_BY_USERNAME,LIST_TODOS_BY_STATUS};
从“@apollo/react hooks”导入{useQuery};
类型ToDolistrops={
用户名:字符串;
showCompleted:布尔值;
};
常量TodoList:FC=({username,showCompleted})=>{
常量{正在加载,错误,数据}=!showCompleted
?useQuery(按用户名列出待办事项,{变量:{USERNAME},轮询间隔:500})
:useQuery(按状态列出待办事项,{变量:{用户名,状态:'COMPLETED'},pollInterval:500});
如果(错误){
返回(
{`Error!${Error}`}

); } 返回( {username} &待办事项 {加载( ) : ( )} ); }; 将默认值导出到列表;
但是,这非常有效,但在构建过程中,由于linting起作用,它会失败并出现错误:

17:7错误响应钩子“useQuery”被有条件地调用。在每个组件中,必须以完全相同的顺序调用React钩子渲染React钩子/钩子规则

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


任何指点都很感激

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

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

在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,
    }
  )

在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,
    }
  )