Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

useLazyQuery hook sets loading to false before data is updated, breaks the useEffect hook #3982

Open
kylehovey opened this issue May 20, 2020 · 0 comments

Comments

@kylehovey
Copy link

kylehovey commented May 20, 2020

The expected behavior is that the loading predicate returned from the useLazyQuery hook should only be false when the data is updated. Since this is used to trigger an effect with useEffect, stale data is used instead of the new data.

The goal is to upload a file using a React-Hooks based component. TinyMCE is used, which takes a file upload handler. The upload requires a URL retrieved from an Apollo Lazy query, which necessitates a useEffect.

const Component = () => {
  const [uploadArgs, setUploadArgs] = useState(null);
  const [getUploadURL, { data, loading, error }] = useLazyQuery(GET_UPLOAD_URL);

  function uploadFile( /* mocked */) {
  }

  function uploadHandler(blob, successCb, failureCb) {
    setUploadArgs([blob, successCb, failureCb]);

    getUploadURL(blob.blobInfo().fileName);
  }

  const [ blob, successCb, failureCb ] = uploadArgs || [];
  const uploadURL = data && data.uploadURL;

  useEffect(() => {
    if (!loading) {
      /**
       * The second file upload, loading is false, but
       * uploadURL is the same as the first upload. After
       * this happens, the data is updated with the new
       * URL, but it is after the effect is triggered.
       * The effect is not triggered again.
       */
      if (uploadURL && blob && successCb && failureCb) {
        uploadFile(uploadURL, blob, successCb, failureCb);
      }
    }
  }, [uploadURL, blob, success, failureCb, loadingCb]);

  return (
    <div>
      <Editor
        uploadHandler={uploadHandler}
      />
    </div>
  );
}

The result was that the old URL was used for the second upload (since loading was false), and shortly after (by looking at the output of console.log right after the useLazyQuery hook), the data was updated. The expectation was that the new URL would be present when loading was false in the useEffect.

Version

npx: installed 1 in 1.291s
  System:
    OS: Linux 4.15 Ubuntu 18.04.4 LTS (Bionic Beaver)
  Binaries:
    Node: 10.18.0 - ~/.asdf/installs/nodejs/10.18.0/bin/node
    Yarn: 1.22.4 - /usr/bin/yarn
    npm: 6.13.4 - ~/.asdf/installs/nodejs/10.18.0/bin/npm
  Browsers:
    Chrome: 81.0.4044.138
    Firefox: 76.0.1
  npmPackages:
    @apollo/react-hooks: ^3.1.3 => 3.1.3 
    @apollo/react-testing: ^3.1.3 => 3.1.3 
    apollo-cache-inmemory: ^1.6.5 => 1.6.5 
    apollo-client: ^2.6.8 => 2.6.8 
    apollo-link: ^1.2.13 => 1.2.13 
    apollo-link-http: ^1.5.16 => 1.5.16 
    apollo-link-state: ^0.4.0 => 0.4.2 
    react-apollo: ^3.1.3 => 2.5.8 
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant