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 thethen()
chain before it, including the one caused by arender()due to a
setState()call.Even if you don’t use
setStatedirectly, you may have the same problem
if some other code you call uses it (for example, a Reduxdispatch()).If you don’t want to catch errors resulting from
setState(), and want
to only catch network failures (let’s imagine yourPromise.resolve()
is actually afetch()), you want to use the secondthen()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.