PresentationInteractive, narrated presentation of the section content.
ContentDetailed description of the section content.
Introduction/Motivation
Why Learn About Error Boundaries?
Imagine you’re using an app, and one small bug crashes the entire application. Frustrating, right? As developers, we want to ensure our apps are resilient. React’s Error Boundaries provide a way to handle errors gracefully, improving the user experience and making debugging easier.
Error Boundaries simulate the try … catch error handling that you know from javascript. But, you are not able to use try … catch in JSX. For example this is impossible:
function App() {
return (
<>
{
try {
return <Foo />
} catch (e) { }
}
</>
)
} Real-world scenario:
You’re working on a dashboard with multiple components (charts, tables, forms). A bug in one chart crashes the entire dashboard! Instead of the app going blank, wouldn’t it be better to show an error message while keeping the rest of the dashboard functional?
Error Boundaries are your solution!
Lecture: Error Boundaries in React
What Are Error Boundaries?
Error Boundaries are React components that catch JavaScript errors anywhere in their child component tree. They display a fallback UI instead of crashing the whole app.
Key Features
- Only catch errors during rendering, lifecycle methods, and constructors.
- Do not catch errors in event handlers.
- Must be class components.
How Do Error Boundaries Work?
Basic Example
Let’s start with a component that might fail:
function BuggyComponent() {
throw new Error("Something went wrong!");
return <div>Will never render</div>;
}
If BuggyComponent crashes, React unmounts the entire app. We prevent this with an Error Boundary.
Creating an Error Boundary
- Define a Class Component:
We normally use functional components and never class components, but this time we will use class components. This course does not cover them, so please just remember the syntax.
import React from "react";
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state to show fallback UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// Log error details for debugging
console.error("Error caught by boundary:", error, errorInfo);
}
render() {
if (this.state.hasError) {
// Fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;2. Wrap the Buggy Component:
Now, when error happens inside the <ErroBoundary /> component, it will correctly catch and handle it!
function App() {
return (
<div>
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
</div>
);
}
Advanced Concepts
1. Customizing the Fallback UI
You can customise the UI of the error message in the render component!
render() {
if (this.state.hasError) {
return (
<div>
<h1>Oops, something broke!</h1>
<button onClick={() => window.location.reload()}>Reload</button>
</div>
);
}
return this.props.children;
}
2. When Not to Use Error Boundaries
- For catching errors in event handlers: Use
try...catchinstead. - Errors outside React components, like network requests, should be handled differently.
Advantages and Limitations
| Advantages | Limitations |
|---|---|
| Prevent the app from crashing | Can’t catch all errors |
| Provide fallback UI for users | Must be class components |
| Log errors for easier debugging | Doesn’t handle async errors |
Conclusion
Key Takeaways
- Error Boundaries improve app resilience by isolating crashes.
- Use
getDerivedStateFromErrorandcomponentDidCatchfor error handling and logging. - They are class components and handle render-phase errors.
Common Pitfalls
- Forgetting to wrap components.
- Using Error Boundaries for non-React errors like API calls.
Best Practice: Use Error Boundaries at critical application layers, like wrapping a dashboard or a router.
No hints available.