why polling of Apollo useQuery don’t call onCompleted?

why polling of Apollo useQuery don’t call onCompleted?


1

I am playing around the code: https://codesandbox.io/s/restless-framework-uldf4q?file=/src/App.js

import React, { Fragment } from "react";
import { gql } from "apollo-boost";
import { useQuery } from "@apollo/react-hooks";

const GET_DOG_PHOTO = gql`
  query Dog($breed: String!) {
    dog(breed: $breed) {
      id
      displayImage
    }
  }
`;

const breed = "dingo";

const App = () => {
  const [count, setCount] = React.useState(0);
  const { loading, error, data, startPolling, stopPolling } = useQuery(
    GET_DOG_PHOTO,
    {
      variables: { breed },
      onCompleted: () => {
        setCount((count) => count + 1);
      }
    }
  );

  if (loading) {
    return <h2>loading</h2>;
  }
  if (error) {
    return <h2>Whoops</h2>;
  }

  return (
    <div>
      <h1> {count}</h1>
      <Fragment>
        <img
          alt="Cute Doggo"
          src={data.dog.displayImage}
          style={{ height: 500, width: 500 }}
        />
        <button onClick={() =>startPolling(500)}>Start</button>
        <button onClick={stopPolling}>Stop</button>
      </Fragment>
    </div>
  );
};

export default App;

In my code, I setCount to count+1 using React.useState in the onCompleted callback? why it just stop counting when polling?

so what is the mechanism here?

3 Answers
3


1

I can also observe that the onCompleted callback is not invoked as expected in the reproducer you provide.

In your CodeSandbox, you are using a 3-year-old deprecated version of the useQuery hook. You could migrate to the latest @apollo/client package, which will solve the issue.

See this migrated CodeSandbox: https://codesandbox.io/s/apolllo-on-completed-n9wzge


1

You can also use notifyOnNetworkStatusChange option as true. It will change the loading state as well every time.

Call api as

const { loading, error, data, startPolling, stopPolling } = useQuery(
    GET_DOG_PHOTO,
    {
      variables: { breed },
      notifyOnNetworkStatusChange: true,
      onCompleted: () => {
        setCount((count) => count + 1);
      }
    }
  );


0

As of Apollo 3.8+, onCompleted only gets called when notifyOnNetworkStatusChange is set to true. However, this is not ideal because it calls onCompleted several times per second, regardless of the pollInterval that you set. You’re better off placing the contents of onCompleted in a useEffect(), with data as a dependency.

const { loading, error, data, startPolling, stopPolling } = useQuery(
  GET_DOG_PHOTO,
  {
    variables: { breed }
  }
);

useEffect(() => {
  setCount((count) => count + 1);
}, [data]);



Leave a Reply

Your email address will not be published. Required fields are marked *