Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

React Error Boundaries Catch Render Errors: Causes, Fixes, Examples & Interview Tips

What are Error Boundaries?

Error boundaries are React components that catch JavaScript errors in their child component tree and show a fallback UI instead of letting the whole application crash. You can think of them as a safety layer around part of your interface.

Without an error boundary, a rendering error can break a large part of the UI. With an error boundary, you can show a friendly message such as "Something went wrong" and keep the rest of the application working.

Why Error Boundaries Matter

  • They stop one broken component from crashing the whole page
  • They let you show a helpful fallback UI
  • They create safer boundaries around risky UI sections
  • They make production apps more resilient
  • They are useful for logging errors to monitoring tools

How Error Boundaries Work

A classic error boundary is a class component that uses two special methods:

  • static getDerivedStateFromError(error) to update state and show fallback UI
  • componentDidCatch(error, errorInfo) to log details about the error

When a child component throws during rendering, the boundary catches it and can render something else instead of the broken subtree.

Basic Error Boundary
import { Component } from 'react'



class ErrorBoundary extends Component {

    constructor(props) {

        super(props)

        this.state = {

            hasError: false,

            error: null

        }

    }



    static getDerivedStateFromError(error) {

        return {

            hasError: true,

            error

        }

    }



    componentDidCatch(error, errorInfo) {

        console.error('Caught by ErrorBoundary:', error)

        console.error('Component stack:', errorInfo.componentStack)

    }



    render() {

        if (this.state.hasError) {

            return (

                <div>

                    <h2>Something went wrong.</h2>

                    <p>{this.state.error?.message}</p>

                </div>

            )

        }



        return this.props.children

    }

}



export default ErrorBoundary

Using an Error Boundary

You wrap the components you want to protect. If one of those components throws an error during rendering, the boundary shows fallback content instead.

Wrap a Risky Component
import ErrorBoundary from './ErrorBoundary'



function BuggyComponent() {

    throw new Error('This component crashed')

}



function App() {

    return (

        <ErrorBoundary>

            <BuggyComponent />

        </ErrorBoundary>

    )

}

If BuggyComponent throws an error while rendering, the rest of the app does not necessarily disappear. Instead, the boundary can show a safe fallback message.

Error Boundaries Do Not Catch Everything

This is one of the most important things to understand. Error boundaries are helpful, but they are not a universal replacement for try...catch.

  • They do catch errors in rendering
  • They do catch errors in lifecycle methods
  • They do catch errors in constructors of child components
  • They do not catch errors in event handlers
  • They do not catch errors in async functions automatically
  • They do not catch server-side rendering errors
  • They do not catch errors thrown inside the boundary itself

Event Handler Errors

If an error happens inside a button click or another event handler, you must handle it yourself with normal JavaScript error handling.

Handle Event Errors with try...catch
function SaveButton() {

    const handleClick = async () => {

        try {

            await saveData()

        } catch (error) {

            console.error('Save failed:', error)

        }

    }



    return <button onClick={handleClick}>Save</button>

}

Granular Boundaries vs One Global Boundary

You can place one error boundary high in the app, or place several smaller boundaries around risky sections. In real projects, smaller boundaries are often better because they isolate failures more precisely.

For example, on a dashboard you might wrap the chart, activity feed, and user list separately. If the chart crashes, the other panels can still render.

Granular Error Boundaries
function Dashboard() {

    return (

        <div>

            <ErrorBoundary>

                <RevenueChart />

            </ErrorBoundary>



            <ErrorBoundary>

                <UserList />

            </ErrorBoundary>



            <ErrorBoundary>

                <ActivityFeed />

            </ErrorBoundary>

        </div>

    )

}

Custom Fallback UI

A good fallback UI should be clear and useful. Instead of only showing a technical error message, you can show a user-friendly message, a reload button, or a retry option.

Fallback UI with Reset Button
class ErrorBoundary extends Component {

    constructor(props) {

        super(props)

        this.state = { hasError: false }

    }



    static getDerivedStateFromError() {

        return { hasError: true }

    }



    resetBoundary = () => {

        this.setState({ hasError: false })

    }



    render() {

        if (this.state.hasError) {

            return (

                <div>

                    <h2>This section failed to load.</h2>

                    <p>Please try again.</p>

                    <button onClick={this.resetBoundary}>Try Again</button>

                </div>

            )

        }



        return this.props.children

    }

}

Using react-error-boundary

Many React developers use the react-error-boundary package because it gives a simpler API and useful helper patterns. It still solves the same problem, but it feels easier to use in modern React applications.

react-error-boundary Example
import { ErrorBoundary } from 'react-error-boundary'

import ErrorFallback from './ErrorFallback'



function App() {

    return (

        <ErrorBoundary

            FallbackComponent={ErrorFallback}

            onError={(error, info) => {

                console.error('Logged error:', error)

                console.error(info.componentStack)

            }}

        >

            <ProfilePage />

        </ErrorBoundary>

    )

}
function ErrorFallback({ error, resetErrorBoundary }) {

    return (

        <div role="alert">

            <h2>Something went wrong</h2>

            <p>{error.message}</p>

            <button onClick={resetErrorBoundary}>Try Again</button>

        </div>

    )

}



export default ErrorFallback

Best Practices for Error Boundaries

  • Wrap risky areas such as dashboards, complex widgets, and remote-data sections
  • Use meaningful fallback messages instead of only technical errors
  • Log errors so you can investigate them later
  • Do not rely on error boundaries for event handler or async errors
  • Keep boundaries focused so a small crash does not blank the whole app

Common Mistakes

  • Expecting error boundaries to catch every type of error
  • Wrapping the entire app with one boundary and nothing else
  • Not logging the error details anywhere
  • Showing confusing fallback text to users
  • Trying to build an error boundary as a normal function component without a library

Summary

Error boundaries make React apps safer by catching rendering errors in child components and replacing broken UI with fallback content. They are especially useful in larger apps where one crashing widget should not take down the rest of the interface.

They are not a replacement for all error handling, but they are an important stability tool. Combined with good logging and targeted placement, they make production React applications much more resilient.

Key Takeaways
  • Error boundaries catch rendering errors in child components.
  • They show fallback UI instead of letting the whole app crash.
  • Classic error boundaries are implemented with class components.
  • getDerivedStateFromError updates the UI after an error occurs.
  • componentDidCatch is used for logging error details.
  • Error boundaries do not catch event handler or async errors automatically.
  • Smaller, targeted boundaries are often better than one large boundary.
  • Libraries like react-error-boundary make modern usage easier.

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.