An error occurs in the UI should break the whole app. To solve this problem, a concept called “Error Boundaries “ is installed in the ReactJs.
What is an Error Boundary?
Error Boundaries are the components to catch errors that occur in the child components, log those errors, and to display a fallback UI. These components help to prevent the crash of the whole component.
A class component becomes an error boundary by defining one or both the lifecycle methods.
- getderivedstatefromprops()
- componentdidcatch()
getderivedstatefromError() is used for rendering a fallback message after an error has thrown.
Componentdidcatch method is used for logging the error information.
NOTE:
Error Boundaries did not catch the errors in the following places,
- Event Handlers
- setTimeout or requestAniationFramecallbacks
- Server-side rendering
- Errors Caused by the error boundary itself
Example:
Let’s see a small example of this concept.
Initially create a file with Details.js
Create a functional component and receive the name and gender as props.
Here the gender taken from the props is male then it throws the error
//Details.js
import React from ‘react’;
import ‘./App.css’;
function Details({ heroName, gender }) {
if (gender === “male”) {
throw new Error(“Males are not allowed”)
}
return (
< div className=”App” >
< p >{heroName}:{gender}
< / div >
);
}export default Details;
Create another file named as Error.js. Here hasError set to false initially in the state method.
In this file, we used these Life cycle methods. here a condition takes place in the render method.
import React from ‘react’;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props)
this.state = {
hasError: false
}
}
static getDerivedStateFromError(error) {
return {
hasError: true
}
}
componentDidCatch(error, errorinfo) {
console.log(errorinfo)
}
render() {
if (this.state.hasError) {
return < h1 >Oops!.Something Went Wrong< /h1 >
} else {
return this.props.children
}
}
}
export default ErrorBoundary;
In the App.js file Error boundary can be placed in two cases:
Case 1: The whole div is wrapped under a single error boundary. In this case, if one component crashes then the other components also crashes.
import React from ‘react’;
import ‘./App.css’;
import Details from ‘./Details’;
import ErrorBoundary from ‘./Error’;
class App extends React.Component {
render() {
return (
< div className=”App” >
< ErrorBoundary >
< Details heroName=”sathya” gender=”female” / >
< Details heroName=”srija” gender=”female” / >
< Details heroName=”sravanth” gender=”male” / >
< /ErrorBoundary >
< /div >
);
}
}
export default App;
Case 2: each component is wrapped with individual error boundaries. So in this case, if one component crashes the others are not affectedimport React from ‘react’;
import ‘./App.css’;
import Details from ‘./Details’;
import ErrorBoundary from ‘./Error’;
class App extends React.Component {
render() {
< ErrorBoundary >
< Details heroName=”sathya” gender=”female” / >
< /ErrorBoundary >
< ErrorBoundary >
< Details heroName=”srija” gender=”female” / >
< /ErrorBoundary >
< ErrorBoundary >
< Details heroName=”sravanth” gender=”male” / >
< /ErrorBoundary >
< /div >
The output for the above two cases is shown below.
Output for the first case:
Output for the second case:
Small advice is to use at least one boundary in the root of your app. This will prevent users from seeing a blank HTML page and perhaps see a nice fallback UI instead.