redux-toolkit icon indicating copy to clipboard operation
redux-toolkit copied to clipboard

Infinite request loop when prefetching data from URL that returns error

Open KostkaBrukowa opened this issue 2 years ago • 2 comments

Hey! I've encountered this problem lately and I was wondering what could I do with that.

I have this piece of code

import * as React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'

export default function App() {
  const { isLoading } = useGetPokemonByNameQuery('bulbasaur')

  return (
    <div className="App">
       {isLoading ? 'Loading...' : <Pokemon name={'bulbasaur'} />} 
    </div>
  )
}

export const Pokemon = ({ name }: { name: string }) => {
  const {} = useGetPokemonByNameQuery(name)

  return (
    <div>
      Pokemon
    </div>
  )
}

Link to codesanbox: LINK

Basically the theme here is:

  1. I want to preload some data, therefore I use useGetPokemonByNameQuery in parent component
  2. When the data is loading I'm not rendering child component.
  3. When the data is preloaded I want to display the data in child component using the same hook

And everything works well when the request was succesful. Unfortunately when the request fails continuously (like in the sandbox there is wrong URL) there is infinite loop of requests coming from RTK query

I was wondering if you could help me with solution here?

KostkaBrukowa avatar Dec 04 '23 07:12 KostkaBrukowa

same problem.

usedlife avatar Feb 20 '24 06:02 usedlife

is there any update, encountering the same problem.

weihe-grabtaxi avatar Feb 21 '24 07:02 weihe-grabtaxi

Just had some help in discord that explained this to me. The problem with this example is that the component is being unmounted/mounted whenever the request is made. Errors won't be re-tried on re-render, but will on mount. The thought process behind this is if you left the page and came back, you'd expect an attempt to be made again, which is what's happening on unmount/remount. If you instead hide/show the component with css but have it always render, you won't get the infinite retry.

In my use cases, since the data is alway possible to be undefined, on the component that actually needs the data, in your case the Pokemon component, just check if you have the data you need, and if not, just return null instead of the rest of the component's contents.

For example:

import * as React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'

export default function App() {
  const { isLoading } = useGetPokemonByNameQuery('bulbasaur')

  return (
    <div className="App">
       {isLoading ? 'Loading...' : }
       <Pokemon name={'bulbasaur'} />
    </div>
  )
}

export const Pokemon = ({ name }: { name: string }) => {
  const {data} = useGetPokemonByNameQuery(name)

  if (!data) return null

  return (
    <div>
      Pokemon
    </div>
  )
}

LordZardeck avatar Dec 06 '24 21:12 LordZardeck

Worth noting this to add to the docs, yeah.

Some notes from Lenz:

that said, RTKQ will only make a request like that on component mount, so unless you unmount and mount repeatedly there won't be extra network requests

markerikson avatar Dec 06 '24 21:12 markerikson