react-apollo
react-apollo copied to clipboard
useLazyQuery hook sets loading to false before data is updated, breaks the useEffect hook
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