Search code examples
reactjsreduxredux-toolkitrtk-query

Redux Toolkit Query - Invalidating old data


I have a MediaCard component, the one containing an img element with an url with a token. This token must first be required in order to get the image. The caveat here is that the token will expire in 30 seconds. It would be something like this:

const MediaCard = () => {

    // This should refetch the token everytime a new component is 
    // mounted and 30 seconds has passed since the last fetch

    const { data: token, error: tokenError, isLoading: tokenIsLoading } = useGetTokenQuery(undefined, { refetchOnMountOrArgChange: 30 });

    if (tokenError) return 'Error'

    if (tokenIsLoading) return 'Loading skeleton'

    return (
       <img url={`/url/${token}/image1.jpg`}
    )
     

This was all working fine when I have only one MediaCard component. The problem started when I mounted the first media card, loaded the token and then render the image. Then, if I let 30 seconds pass, when I try to mount a new MediaCard, the hook will start refetching the token, but keeping the old data. That brought two different issues:

  1. When the new component mount, as we have an expired token as data, the image would fail to load. Then, after the new token was received, the image would re-render and then worked.
  2. Once the new token was received, all the previous mounted images would re-render. I would like that once the image is render with a valid token to keep that way and don't render again.

Maybe the solution is not regarding RTK Query but React itself.


Solution

  • The point of RTK Query "queries" is to "reflect" the state of the server - which means that we assume that a request for a certain endpoint with the same arguments will always have the most "up-to-date" response (treating those as REST resources) - and will keep all those query responses synchronized with each other over component boundaries.

    In your case, it seems you don't want that, you want these to be local to the component. To be honest, you don't need a global state like Redux for that - you could just make the request and save the response into local component state.

    If you want to use RTK Query for it nonetheless, you should probably go for mutations instead of queries here - since mutation results are unique per component. And just trigger the mutation trigger in a useEffect directly after component mount.