Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

461
Visualizações
Why shouldn't I use catch() to handle errors in React useEffect API calls?

On this page of the React docs:

https://reactjs.org/docs/faq-ajax.html

A code comment says...

Note: it's important to handle errors here instead of a catch() block so that we don't swallow exceptions from actual bugs in components.

...about handling errors in the second argument to the second .then after fetch. The complete snippet from the docs is:

  useEffect(() => {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

It doesn't elaborate on this advice, and I've seen many examples of working React code using catch to handle errors from API calls. I've tried Googling but can't find any clarification.

Could someone please give me a more detailed explanation as to why I shouldn't use catch to deal with errors that arise when making a fetch API call in a useEffect hook?

Or are there some situations when it's ok to do so, but others when it's not?

What is meant by "swallow exceptions [...] in components" ?

Does this rule/guideline apply to all of React, or just to API calls?

Or just to the useEffect hook or componentDidMount lifecycle method?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Everything I can find on this seems to link back to this github issue circa 2016. I'll quote verbatim from there since it doesn't appear to have been covered on Stack Overflow before and it explains things pretty thoroughly:


.then(() => {
  this.setState({ loaded: true })
})
.catch(()=> { 
  console.log('Swallowed!') 
});

Your catch() handler is going to catch any error thrown in the then() chain before it, including the one caused by a render() due to a setState() call.

Even if you don't use setState directly, you may have the same problem if some other code you call uses it (for example, a Redux dispatch()).

If you don’t want to catch errors resulting from setState(), and want to only catch network failures (let’s imagine your Promise.resolve() is actually a fetch()), you want to use the second then() argument instead:

componentDidMount() {
  Promise.resolve()
  .then(() => {
      this.setState({ loaded: true })
  }, (err) => {
    console.log('An error occurred (but not in setState!)', err);
  });
}

In this case, unless you catch() later in the chain, the error in render() will be uncaught and, with a good Promise polyfill (or with native Promises in Chrome and maybe other browsers), displayed.


Edit: following the answer from @Martin I went and tested this, and I can confirm that this no longer appears to be a relevant concern. Render errors from setState are not caught in any version of React from v16.0 onwards, and since useState was only introuduced in v16.8, it doesn't seem possible that this could ever have been an issue for hooks.

Here is a codesandbox which demonstrates the original issue in the older versions of React.

over 4 years ago · Santiago Trujillo Relatório

0

It is a copy-and-paste error of the example's author. The first example uses the component state of a class based component: this.setState() causes a synchronous re-render (or at least this was the case with react v15.0 in 2016, not sure if it holds true today). Therefore the warning comment and the use of the second arg to .then(onResolve, onReject) is justified. The second example uses the useState hook of a function component: setState causes no synchronous re-render only an asynchronous re-render. Therefore the warning comment and the use of the second arg to .then(onResolve, onReject) is not justified.

To illustrate this: with useState hooks you can call multiple updaters and they all will only take effect in one re-render.

const [a, setA] = useState();
const [b, setB] = useState();
const [c, setC] = useState();

const updateState = () => {
  setA('foo');
  setB('bar');
  setC('buz');
  // will only cause one single re-render
}

and therefore its perfectly fine to use catch

useEffect(() => {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        }
      )
      .catch(
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda