RevereCRE/relay-nextjs

"Expected preloadedQuery to not be disposed yet." error

solher opened this issue ยท 7 comments

First of all, thank you for the library ๐Ÿ™

For one of my component, I'm using the useQueryLoader + usePreloadedQuery hooks.

Everything was working flawlessly until I updated from React 17.0.2 to 18.1.0. I started getting:

next-dev.js?3515:25 Warning: usePreloadedQuery(): Expected preloadedQuery to not be disposed yet. This is because disposing the query marks it for future garbage collection, and as such query results may no longer be present in the Relay store. In the future, this will become a hard error. 
    at eval (webpack-internal:///./components/index/UserBeats.tsx:22:26)
    at LoadableImpl (webpack-internal:///./node_modules/next/dist/shared/lib/loadable.js:101:38)
    at Suspense
    at eval (webpack-internal:///./components/index/IndexLoggedIn.tsx:120:69)
    at LoadableImpl (webpack-internal:///./node_modules/next/dist/shared/lib/loadable.js:101:38)
    at Suspense
    at eval (webpack-internal:///./pages/index.tsx:45:73)
    at div
    at div
    at eval (webpack-internal:///./components/nav/NavWeb.tsx:50:27)
    at RelayEnvironmentProvider (webpack-internal:///./node_modules/react-relay/lib/relay-hooks/RelayEnvironmentProvider.js:21:24)
    at FirebaseContextProvider (webpack-internal:///./lib/firebase.tsx:125:29)
    at MyApp (webpack-internal:///./pages/_app.tsx:112:27)
    at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:20746)
    at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:23395)
    at Container (webpack-internal:///./node_modules/next/dist/client/index.js:323:9)
    at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:825:26)
    at Root (webpack-internal:///./node_modules/next/dist/client/index.js:949:27)

It's not crashing or anything, it's just a warning and it actually disappears when going to prod, but I was wondering if it would ring a bell to you. I really cannot find anything online :/

I haven't seen this error in production mode at all, only sometimes in dev when interrupting the loading process. That said, we're still on React 17 at Revere so it makes sense. I'll try upgrading soon and update here!

If you are using strict mode react renders the component twice. If you use an effect to dispose of your query you might get this error. In that case in your effect fetch the preload the query again.

  useEffect(() => {
    if (_data.isDisposed) revalidate(); // this function preloads the query again

    return () => _data.dispose();
  }, []);

We have this issue too since we started using React 18 with strict mode.

@phikes thanks for your input, a quick search in this codebase highlighted this piece of code:

useEffect(() => {
loadQuery(queryVariables);
return disposeQuery;
}, [loadQuery, disposeQuery, queryVariables]);

Would this be the cause? the <Component child would receive a disposed reference to preloadedQuery when react strict mode renders twice.

however the effect that disposes the query on unmount also calls load on mount, so I am not sure if the issue comes from here.

I am not sure, I actually just stumbled across this issue. I had the same problem with another stack. But this looks very much like the culprit to me, yes. It looks more like a "real" race condition here.

We have a new version we've been testing internally that replaces this code path I'll work on releasing soon!

@rrdelaney Any update on this issue?

@rrdelaney Any update on this issue?

Hey Jason, we've removed that exact codepath in 2.0. Are you continuing to see the issue after upgrading?