Relay: useLazyLoadQuery breaks with GC after quick unmount -> mount

Created on 18 Dec 2020  路  17Comments  路  Source: facebook/relay

useLazyLoadQuery is returning undefined without refetching when the following occurs:

  1. A component using useLazyLoadQuery mounts and eventually unsuspends.
  2. This component is then unmounted in one place to be mounted in a separate spot in the JSX.

The following error warning is printed in the console:

Warning: Relay: Expected to have been able to read non-null data for fragment
`ProofOfBugQuery` declared in `useLazyLoadQuery()`, since fragment reference 
was non-null. Make sure that that `useLazyLoadQuery()`'s parent isn't holding on
to and/or passing a fragment reference for data that has been deleted.

This problem is not occuring when garbage collection is disabled, either by running environment.retain() on that query or by setting a large gcReleaseBufferSize in the provider.

Here is a runnable example to reproduce the bug:

import React, { useEffect, Suspense, useState } from 'react';
import { graphql, useLazyLoadQuery } from 'react-relay/hooks';

const Content = ({ onMount }) => {
  const data = useLazyLoadQuery(
    graphql`
      query ProofOfBugQuery {
        viewer {
          x
        }
      }
    `,
    {},
  );

  useEffect(() => {
    onMount();
  }, []);

  return <div>{data ? 'Loaded' : 'ERROR, data is undefined'}</div>;
};

const ProofOfBug = () => {
  const [switched, setSwitched] = useState(false);

  const onMount = () => {
    setTimeout(() => setSwitched(true), 1000);
  };

  return (
    <Suspense fallback="Loading">
      <div>{switched ? null : <Content onMount={onMount} />}</div>
      <div>{switched ? <Content onMount={onMount} /> : null}</div>
    </Suspense>
  );
};

export default ProofOfBug;

This is the version of Relay in use:

    "relay-compiler": "10.1.0",
    "relay-compiler-language-typescript": "13.0.2",
    "relay-config": "10.1.0",
    "react-relay": "0.0.0-experimental-c818bac3",
    "relay-runtime": "10.1.0",

Hopefully this bug report is understandable. Please let me know if I can provide any more helpful information!

All 17 comments

Possibly related to #3215 and #3270 ?

Here is a repo that reproduces the issue (you need to add your github key to the environment) https://github.com/imownbey/relay-examples. Note how I had to comment out https://github.com/imownbey/relay-examples/blob/master/issue-tracker/src/RelayEnvironment.js#L62 to make it throw the error

It also seems to only happen ~50% of the time which kind of makes sense?

thanks for reporting @saivann and @imownbey, and apologies for the delay, I'm going to look into this. quick question, are you using concurrent mode when this happens, or not?

@jstejada Thank you!! All the examples we provided did not use concurrent mode. Please let us know if we can do anything to help further. :pray:

@saivann, to confirm, did this problem start happening when you upgraded relay?

@jstejada We started using Relay on 0.0.0-experimental-c818bac3 (the version on which we reproduced this problem) so we do not know if this is a regression or long term bug in the library.

hey @saivann, what version of react are you using?

react and react-dom are locked to 16.13.1 in yarn.lock

@jstejada Were you able to reproduce / find the cause? @imownbey provided a repo example of the problem here in case it helps.

hey, not yet, but working on it

i was able to reproduce and have a change that should be landing today or tomorrow

@saivann @imownbey, this should be fixed with 24bac58f46bc7694f069e46c4493201dfea60786, so closing this issue. if you still find issues feel free to reopen

@jstejada Thank you so much! Seems like this commit is not yet published to npm for relay-experimental? Any advice on how we can update and test?

we haven't cut a new experimental release, will let you know when we do

Looks like the v11 RC fixes it, thank you so much!!

Was this page helpful?
0 / 5 - 0 ratings