TIL, 2023-04-20
How to handle errors in React: full guide
- Starting from version 16, an error thrown during React lifecycle causes the entire app to unmount itself if not stopped.
- Before, components would be preserved on the screen. Now, an uncaught error will destroy the entire page.
try catch
- can do also in promises.- This doesn’t work with
useEffect
because it’s called asynchronously after render.
- This doesn’t work with
try {
useEffect(() => {
throw new Error('Hulk smash!');
}, [])
} catch(e) {
// useEffect throws, but this will never be called
}
- This is the way to fix this:
useEffect(() => {
try {
throw new Error('Hulk smash!');
} catch(e) {
// this one will be caught
}
}, [])
try catch
doesn’t work well in children components.- This doesn’t work:
const Component = () => {
try {
return <Child />
} catch(e) {
// still useless for catching errors inside Child component, won't be triggered
}
}
- This is happening because when we write
<Child />
, we are not actually rendering this component. We are creating a componentElement
, which is just a component’s definition. -
Other limitation: setting state during render is a no-no.
- Infinite re-renders:
const Component = () => {
const [hasError, setHasError] = useState(false);
try {
doSomethingComplicated();
} catch(e) {
// don't do that! will cause infinite loop in case of an error
// see codesandbox below with live example
setHasError(true);
}
}
React ErrorBoundary
component
- A special API that turns a regular component into a
try/catch
statement in a way, only for React declarative code.