Data not being refetched when released from cache. Getting `fragmentresource.missing_data` when trying to access released data.
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
This is a TL;DR of the problem, you can also find the explanation in [this repository](https://github.com/productboard/relay-missing-data-bug) which contains runnable example. Please refer to that repository for more screenshots and images if you find the explanation below unsatisfactory.
I am describing this problem with Github API but I have run into the same problem when using my company's internal API, it does not seem to be related to server at all.
I have a component that uses `useLazyLoadQuery` hook with combination of `usePaginationFragment` hook to search through repositories. I use `` as a filter. When I type into the input box value `123456789abc` somewhat "quickly" I fire off multiple requests.
At this point all works as expected but as soon as I start deleting characters from the input box and I get to just one character `1` being left into the input box, instead of Relay refetching the data I get `undefined`.
This is what UI looks like:
[video01.webm](https://user-images.githubusercontent.com/5990424/231101888-14f5fdd1-5961-451a-a8c7-25000f391f97.webm)
My code contains logging function which in this situation prints out `fragmentresource.missing_data`. Looking at the source code it points to [this](https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/FragmentResource.js#L492) part of the codebase.
The generated Typescript types seem to be unreliable at this point since the result should be data or `null` but in my case it's `undefined`.
I'm using default settings for my environment. This means the garbage collector retains 10 items and my network policy is `store-or-network`. **The issue is that the missing data should be re-fetched** as far as I know and not end up `undefined`.
I tried debugging this problem with Relay dev tools and I can see older data being released as soon as I get to 10th or 11th character typed into the input box so I confirmed that the data is indeed not there.
_This does not happen if I let the requests finish (!)_. This means that if I type character one-by-one and then start deleting the characters, the data is actually refetched, in UI it looks like this:
[video03.webm](https://user-images.githubusercontent.com/5990424/231102798-fffb053f-b912-43ed-99ad-e9c157eaf942.webm)
Notice that when I get to single `1` character, the loading UI is shown.
I realize that in real world scenario one would add throttle function to the input but in any case, I would expect Relay to be more robust in this regard. I also know that I could increase the limit of items being retained in the garbage collector but that does not really solve the problem as it would appear sooner or later (I'm using constrained example here on purpose).
I could use defensive code and check `!data.search` but that feels like a work-around and my UI will end up in inconsistent state. Since this is not "error" it will not bubble up to error boundary.
~~I could replace `useLazyLoadQuery` with combination of `useQueryLoader` + `usePreloadedQuery` which according to documentation makes sure to retain data in the cache as long as the component is mounted. However in this scenario it might not be the best solution as it could lead to higher memory consumption when user is using the search for too long and again, it doesn't really explain why data is not being re-fetched.~~
After researching this for couple of days I concluded that this is most likely a bug. If I'm using Relay in a wrong/non-idiomatic way, could you please point it out? I tried reaching to community via Discord but got no answer there.
Please refer to my example in the repository I mentioned above: https://github.com/productboard/relay-missing-data-bug
Contributor guide
Assessment
This issue has not been assessed yet.