尝试使用 react-apollo-hooks 在函数中调用 useQuery

ko_*_*_ma 14 javascript reactjs graphql react-apollo react-hooks

我想在需要时调用 useQuery,

但是 useQuery 不能在函数内部。

我的尝试代码是:

export const TestComponent = () => {
...
  const { data, loading, error } = useQuery(gql(GET_USER_LIST), {
    variables: {
      data: {
        page: changePage,
        pageSize: 10,
      },
    },
  })
  ...
  ...
  const onSaveInformation = async () => {
    try {
      await updateInformation({...})
      // I want to call useQuery once again.
    } catch (e) {
      return e
    }
}
...
Run Code Online (Sandbox Code Playgroud)

如何多次调用 useQuery?

我可以随时调用它吗?

我找了几个网站,但找不到解决方案。

Yus*_*bek 40

来自阿波罗文档

当 React 挂载并渲染调用 useQuery 钩子的组件时,Apollo Client 会自动执行指定的查询。但是,如果您想执行查询以响应不同的事件,例如用户单击按钮,该怎么办?

useLazyQuery 钩子非常适合执行查询以响应组件渲染以外的事件

我建议useLazyQuery。简单来说,useQuery将在您的组件渲染时运行,您可以使用skipoption 跳过初始运行。并且有一些方法可以随时重新获取/获取更多数据。或者你可以坚持useLazyQuery

例如,如果您只想在用户单击按钮或滚动到底部时获取数据,则可以使用useLazyQuery钩子。

  • 根据帖子标题,这个答案应该是已接受的答案。让我投赞成票吧。 (4认同)

Her*_*rku 18

useQuery是一个声明性的 React Hook。它并不意味着在接收数据的经典函数的意义上被调用。首先,确保理解 React Hooks 或者暂时不使用它们(Stackoverflow 上 90% 的问题都是因为人们试图一次学习太多东西)。Apollo 文档对于react-apollo使用渲染道具的官方包非常有用。这同样有效,一旦您了解了 Apollo ClientHooks,您就可以进行一些重构。所以你的问题的答案:

如何多次调用 useQuery?

你不会多次调用它。当查询结果可用或更新时,组件将自动重新渲染。

我可以随时调用它吗?

不,钩子只能在顶层调用。相反,数据在您的函数中可以从上层作用域(闭包)获得。

updateInformation应该是一个更新应用程序缓存的突变,它再次触发 React 组件的重新渲染,因为它“订阅”了查询。在大多数情况下,更新是全自动的,因为阿波罗将通过组合标识的实体__typenameid。下面是一些伪代码,说明了突变如何与突变一起工作:

const GET_USER_LIST = gql`
  query GetUserList {
    users {
      id
      name
    }
  }
`;

const UPDATE_USER = gql`
  mutation UpdateUser($id: ID!, $name: String!) {
    updateUser(id: $id, update: { name: $name }) {
      success
      user {
        id
        name
      }
    }
  }
`;

const UserListComponen = (props) => {
  const { data, loading, error } = useQuery(GET_USER_LIST);
  const [updateUser] = useMutation(UPDATE_USER);

  const onSaveInformation = (id, name) => updateUser({ variables: { id, name });

  return (
    // ... use data.users and onSaveInformation in your JSX
  );
}
Run Code Online (Sandbox Code Playgroud)

现在,如果用户的名称通过突变更改,Apollo 将自动更新缓存并触发组件的重新渲染。然后组件会自动显示新数据。欢迎使用 GraphQL 的力量!

  • 如果有人仍然没有得到完整的了解,这里有一个很好的例子。https://ultimatecourses.com/blog/graphql-client-side-integration-with-apollo-hooks (3认同)

dwu*_*u39 7

有回答提到了如何使用 useQuery ,以及使用 useLazyQuery 的建议。我认为关键的一点是了解 useQuery 与 useLazyQuery 的用例,您可以在文档中阅读。下面我尝试从我的角度来解释一下。

useQuery是“声明性的”,就像 React 的其余部分一样,尤其是组件渲染。这意味着当 state 或 props 改变时,你应该期望 useQuery 在每次渲染时被调用。所以用英语来说,就像是“嘿 React,当事情发生变化时,这就是我希望你查询的内容”。

对于useLazyQuery,文档中的这一行是关键:“useLazyQuery 挂钩非常适合执行查询以响应组件渲染以外的事件”。用更一般的编程语言来说,这是“势在必行”的。这使您能够根据需要调用查询,无论是响应状态/属性更改(即使用 useEffect)还是响应按钮单击等事件处理程序。用英语来说,就像“嘿 React,这就是我想要查询数据的方式”。


小智 6

您可以使用从 useQuery 返回的 fetchMore(),它主要用于分页。

const { loading, client, fetchMore } = useQuery(GET_USER_LIST);
const submit = async () => {
    // Perform save operation

    const userResp = await fetchMore({
      variables: {
          // Pass any args here
      },
      updateQuery(){

      }
    });
    console.log(userResp.data)
  };
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多内容:fetchMore

您还可以使用 useLazyQuery,但是它会给您一个返回void的函数,并且数据在函数外部返回。

const [getUser, { loading, client, data }] = useLazyQuery(GET_USER_LIST);
const submit = async () => {
    const userResp = await getUser({
      variables: {
        // Pass your args here
      },
      updateQuery() {},
    });
    console.log({ userResp }); // undefined
  };
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多内容:useLazyQuery