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?
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);
}
)
}, [])
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments