Trying call useQuery in function with react-apollo

2019-08-17 12:20发布

问题:

I want to call useQuery whenever I need it,

but useQuery can not inside the function.

My trying code is:

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
    }
}
...

How do I call useQuery multiple times?

Can I call it whenever I want?

I have looked for several sites, but I could not find a solutions.

回答1:

useQuery is a declarative React Hook. It is not meant to be called in the sense of a classic function to receive data. First make sure to understand React Hooks or simply not use them for now (90% of questions on Stackoverflow happen because people try to learn to many things at once). The Apollo documentation is very good for the official react-apollo package, which uses render props. This works just as well and once you have understood Apollo Client and Hooks you can go for a little refactor. So the answers to your questions:

How do I call useQuery multiple times?

You don't call it multiple times. The component will automatically rerender when the query result is available or gets updated.

Can I call it whenever I want?

No, hooks can only be called on the top level. Instead the data is available in your function from the upper scope (closure).

Your updateInformation should probably be a mutation that updates the application's cache, which again triggers a rerender of the React component because it is "subscribed" to the query. In most cases the update happens fully automatically because Apollo will identify entities by a combination of __typename and id. Here some pseudocode that illustrates how mutations work together with mutations:

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
  );
}

Now if the name of a user changes via the mutation Apollo will automatically update the cache und trigger a rerender of the component. Then the component will automatically display the new data. Welcome to the power of GraphQL!