via GIPHY

Error boundaries introduced from React 16. This is the way to catch and handle JavaScript errors that occur in the React Components.

Error boundaries only catch errors that occur in a lifecycle method, render method, and inside Hooks like useEffect.

According to the React , error boundaries can't handle these errors

  • Event handlers
  • Asynchronous code
  • Server-side rendering
  • Errors thrown in the error boundary itself (rather than its children)

To Use an Error Boundary Feature Simply Create a Class Based Component

Our class component should also have at least three methods:
1. A static method called getDerivedStateFromError, which is used to update the error boundary’s state
2. A componentDidCatch lifecycle method for performing operations when our error boundaries catch an error, such as logging to an error logging service
3. A render method for rendering our error boundary’s child or the fallback UI in case of an error

import React from 'react';
export class MyAppErrorBoundary extends React.Component{
    constructor(props){
        super(props);
        this.state = {hasError:false};
    }

    static getDerivedStateFromError(error) {
        // Update state so the next render will show the fallback UI.
        return { hasError: true };
      }
    
    componentDidCatch(error, info){
        // used to log the error
        console.log('Component Did Catch ::: Error Occur ', error, 'Info ',info);
        //this.setState({hasError: true});
    }
    render(){
        if(this.state.hasError){
            return <h1 className="alert-danger">OOPS Something Went Wrong...</h1>
        }
        else{
            return this.props.children;
        }
    }
}

Error Propgate to the Errror Boundary.

Error Boundary

To Use Error Boundary in App.jsx file

import logo from './logo.svg';
import './App.css';
import Home from './pages/Home';
import { MyAppErrorBoundary } from './shared/components/Error';

function App() {
  return (
    <MyAppErrorBoundary>
   <Home/>
   </MyAppErrorBoundary>
  );
}

export default App;

Let's Generate Some Error and See the Effect.

import React from 'react'
import { useState } from 'react'
import Login from '../components/Login'
import Register from '../components/Register'
import { UserContext } from '../app/user-context'

const Home = () => {
  
  const [screenFlag, setScreenFlag] = useState(true);
  const [userInfo, setUserInfo] = useState();
  throw new Error('Home Error...'); // Throwing Error From Here
  const toggleIt = ()=>{
    
        setScreenFlag(!screenFlag);
  }  
  return (
   <div className='container'>
        <button className='btn btn-info' onClick={toggleIt}>{screenFlag?"Login":"Register"}</button>
        <UserContext.Provider value={{user:userInfo,setUser:setUserInfo}}>
        {screenFlag?<Login/>:<Register/>}
        </UserContext.Provider>
   </div>
  )
}

export default Home

Final Outcome if Error Generated..

That's All Folks , Happy Learning :)