Error boundaries in React framework version 16
The React framework version 16 is out now, and there are many exciting changes. One feature that excites me is improved error handling. In previous versions, if a runtime error occurred while rendering a web page, the React framework would be in a broken state.
React 16 now allows you to use error bounds instead of unmounting the entire application every time an error occurs. Think of error boundaries as a mechanism similar to try-catch statements in programming, but implemented by the React component.
The error boundary is a React component. It and its child components form a tree structure that captures errors everywhere in JavaScript, logs errors, and displays a back-up interface that prevents the user from directly seeing crashes in the component tree.
There’s a new kind of lifecycle function that’s involved here called componentDidCatch(Error, info). No matter what class component defines this function, it becomes an error boundary.
With error boundaries, the entire React program does not mount even if a component results in an error. Only the faulty component will show a back-up screen, and the entire program will still work perfectly.
Now we’ll show you how to use error boundaries in React. Let’s take the example of an e-commerce site that has a product listing page that shows all the products that are being sold.
The resulting page should look something like this:
Note the last product card, where you can see the error in the template. React 16’s error bounds feature allows us to insert a backup interface template into that particular component, and the entire application will still render normally.
Error boundary class components can be created by:
import React, { Component } from 'react';
import { Card, CardMedia, CardTitle, CardText } from 'react-toolbox/lib/card';
const style = {
width: '350px',
marginLeft: '20px',
marginTop: '20px',
display: 'inline-block'
};
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
componentDidCatch(error, info) {
this.setState({
hasError: true
});
}
render() {
if(this.state.hasError) {
return (
<Card style={style}>
<CardMedia
aspectRatio="wide"
image="https://cdn.dribbble.com/users/1078347/screenshots/2799566/oops.png"
/>
<CardTitle
title="Sorry Something went wrong!!!"
subtitle="Error catched by error boundary of react 16"
/>
</Card>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
Copy the code
We can then place any component package inside the error bound component to catch the error and display the backup screen.
Such as:
<ErrorBoundary>
<ProductCard />
</ErrorBoundary>
Copy the code
The componentDidCatch() function is used much like a catch {} block in JavaScript, but only for components. Only class components can be error bounds.
Inside componentDidCatch() we set the hasError state to true. Then check that state in the render method. If the error state is true, render the backup screen; If false, render the React component interface as a child.
There are three main parts to this program:
-
ProductList Component (Smart Component)
-
Presentational Component
-
Presentational Component
I used the React Toolbox for the web page style.
The ProductList component code is as follows:
import React, { Component } from 'react'; import ErrorBoundary from './ErrorBoundary'; import Product from './Product'; export default class ProductList extends Component { constructor(props) { super(props); this.state = { products: [{ name: 'iPhone 7', price: 'Price: 650$', imageUrl: 'https://i.ytimg.com/vi/7Jd7P42qaFM/maxresdefault.jpg' }, { name: 'Tesla', price: 'Price: 950$', imageUrl: "Https://www.tesla.com/tesla_theme/assets/img/models/v1.0/slideshow/Red_Bay-1440.jpg?20171005"}, {name: 'Iron', price: 'Price: 50$', imageUrl: 'https://images-na.ssl-images-amazon.com/images/I/41BW0yDhVeL._SX355_.jpg' }, { name: 'The Kite Runner', price: 'Price: 30$', imageUrl: 'https://images.gr-assets.com/books/1484565687l/77203.jpg' }, { price: 'Price: 950$', imageUrl: 'https://www.tesla.com/tesla_theme/assets/img/models/v1.0/slideshow/Red_Bay-1440.jpg?20171005'}}; } renderProducts() { return this.state.products && this.state.products.map((product) => { return ( <ErrorBoundary key={product.name}> <Product product={product} /> </ErrorBoundary> ); }); } render() { return ( <div className="productList" style={{ marginTop: '40px' }}> { this.renderProducts() } </div> ); }}Copy the code
You can see that the product component is wrapped inside the error boundary.
The code for the Product component is:
import React from 'react';
import { Card, CardMedia, CardTitle, CardText } from 'react-toolbox/lib/card';
const style = {
width: '350px',
marginLeft: '20px',
marginTop: '20px',
display: 'inline-block'
};
const Product = (props) => (
<Card style={style}>
<CardMedia
aspectRatio="wide"
image={props.product.imageUrl}
/>
<CardTitle
title={props.product.name.toUpperCase()}
subtitle="Subtitle here"
/>
<CardText>{props.product.price}</CardText>
</Card>
);
export default Product;
Copy the code
In the above Product. The js code, we call the props.. The Product name. The toUpperCase () function.
So whenever a product has no name, the toUpperCase function will be called for an object with undefined undefined value. This error occurred in the past and would eventually cause the entire React program to be unmounted.
But now that we have error boundaries, we can catch these errors and render a back-up interface. Here’s an example:
Hopefully this example will help you understand the error boundary of React 16.
React 16 also comes with a lot of cool features that I’d like to discuss in the next article.
The entire code for the demo above can be found on my Github page, linked to:
vivek12345/React-16—Error-Boundaries _React-16—Error-Boundaries – Repo to demonstrate the usage of Error Boundaries in React 16_github.com
For more information, see the links below:
- React 16 error handling
- From egghead. IO: React Error handling
- React
- Reactjs
- Error handling
- JavaScript