React Error Handling
Always there is a bugs in development and it's better to know to how we can handle them. In this post I am going to share about how to handle them in React.
Try/Catch
Let's start talking about try/catch method which is really simple but useful at the same time. We just can use it for imperative code and event handlers which are often used in a declarative way in react.
Event handler using Try/Catch
The provided code demonstrates a basic event handler that employs a try/catch block. Within the try block, there is a comment indicating the potential presence of code performing operations like making API calls using fetch or internal API functions. The try block attempts to execute these operations, while the catch block is responsible for capturing any encountered errors in case the operations within the try block fail.
const MyComponent = () => {
const [error, setError] = useState(null)
handleClick() {
try {
// Do something that could throw
} catch (error) {
setError(error);
}
}
if (error) {
return <h1>Caught an error.</h1>
}
return <button onClick={this.handleClick}>Click Me</button>
}
Common mistakes
When utilizing the try/catch method, it is essential to be mindful of certain considerations. As this method operates in an imperative manner, it can lead to complications when employed alongside React lifecycle methods like useEffect, children components, and state updates during rendering.
Example with useEffect (Wrong)
This will never work, since we can't wrap useEffect with try/catch.
Recommended by LinkedIn
try{
useEffect(() => {
throw new Error("Main Error!")
},[])
}catch(e){
// useEffect throws, but this will never be called
}
Example with useEffect (Right)
This is an example of how to use try/catch with useEffect the right way.
useEffect(() => {
try{
throw new Error("Main Error!")
}catch(e){
// this one will be caught
}
}, [])
Example with children components
We also can not do this cause it will be useless cause it will never catch an error since the child component belongs to the lyfecycle method of the react virutal DOM.
const Component = () => {
try {
return <Child />
} catch(e) {
// still useless for catching errors inside Child component, won't be triggered
}
}
Example setting state during render
The following example will just cause an infinite loop in case of an error.
const Component = () => {
const [error, setError] = useState(false);
try{
something();
}catch(e){
setError(e)
}
}
We could use something like this though, where we will set the state inside a useEffect but we will also have a try/catch at the render but in case of error it will return an error screen instead of setting some state.
const Component = () => {
const [error, setError] = useState(false);
useEffect(() => {
try{
//something
}catch(e){
setError(true);
}
},[])
try{
something();
}catch(e){
return <ErrorScreen/>
}
if(error) return <ErrorScreen/>
return <NiceComponent/>
}