3

I have a React function component (a route component) that should do something when it is unmounted (i.e. the user clicks the browser Back button) and contains the following relevant lines:

// ...

const params = useParams<ISomeInterfaceHere>();

// ...

// I verified that `data` below actually loads but it does not last until the component unmounts.
const { data, isLoading, isError } = useGetSomethingQuery(params.x, {
  refetchOnMountOrArgChange: true,
});

// ...

useEffect(() => {
  return () => {
    // current state:
    //
    // isLoading === true
    // isError === false
    // data === undefined
  };
}, []);

// ...

Does it have to do with the useParams hook which is from the react-router package? Is this a bug in RTKQ or, if not, what is the defined behavior? And, most importantly, how can I get the last defined value of data just before the component unmounts?

There are no error messages.

Update 1

I use:

"react": "^16.14.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"@reduxjs/toolkit": "^1.6.0",

Update 2

I am sure that the params are not getting updated, not even params.x. I also upgraded to @reduxjs/toolkit v1.6.1 and I have the same issue.

Update 3

A code sandbox with the isolated issue is here. It looks to me like it is a bug in RTKQ.

Update 4

I opened a GH bug report here.

silviubogan
  • 3,343
  • 3
  • 31
  • 57
  • `refetchOnMountOrArgChange`. just by going by the name of it, looks like data will be fetched again in case any of the params are changed. You are sure the params are not getting updated ? – kumarmo2 Aug 07 '21 at 05:42
  • @kumarmo2 Yes, I am sure. – silviubogan Aug 07 '21 at 05:49

1 Answers1

1

You are creating that cleanup callback on first render. From that moment on, that callback will hold on to stale variables from that first render until it is executed, even if hundreds of renders occur in-between.

This has nothing to do with RTKQ - it's just how React works. If you want access to up-to-date values in that cleanup, you'll have to tunnel it through a ref:

const { data, isLoading, isError } = useGetSomethingQuery(params.x, {
  refetchOnMountOrArgChange: true,
});

const ref = useRef({data, isLoading, isError})
useEffect(() => { ref.current = {data, isLoading, isError} }, [data, isLoading, isError])

// ...

useEffect(() => {
  return () => {
    console.log(ref.current)
  };
}, []);
phry
  • 35,762
  • 5
  • 67
  • 81