admin管理员组

文章数量:1410697

I'm using an Error Boundary in my React application to catch errors in child components. However, whenever an error occurs, the entire component tree under the Error Boundary gets replaced by the fallback UI, resulting in a blank screen.

Instead of completely unmounting the previous component, I want to:

Keep the existing UI intact Show an alert or a popup notifying the user that there was an issue loading the next component Ensure the app remains usable despite the error Is there a way to achieve this in React, where the Error Boundary catches the error but does not unmount the existing UI? Any insights or best practices would be greatly appreciated!

I'm using an Error Boundary in my React application to catch errors in child components. However, whenever an error occurs, the entire component tree under the Error Boundary gets replaced by the fallback UI, resulting in a blank screen.

Instead of completely unmounting the previous component, I want to:

Keep the existing UI intact Show an alert or a popup notifying the user that there was an issue loading the next component Ensure the app remains usable despite the error Is there a way to achieve this in React, where the Error Boundary catches the error but does not unmount the existing UI? Any insights or best practices would be greatly appreciated!

Share asked Mar 4 at 12:01 megmeg 1237 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

you can do this by leveraging providers, useContext, and hooks. You can also use a library such as redux to manage that context. for a quick think. this should give you an idea on how to implement it.

function useErrorBoundary() {
  const [error, setError] = useState(null);

  useEffect(() => {
    return () => setError(null);
  }, []);

  return [error, setError];
}

function ErrorAlert({ error, onDismiss }) {
  if (!error) return null;
  
  return (
    <div>
      An error occurred while loading content
      <button 
        onClick={onDismiss}
        style={{ marginLeft: '10px' }}
      >
        Dismiss
      </button>
    </div>
  );
}

function GentleErrorBoundary({ children }) {
  const [error, setError] = useState(null);
  
  const errorHandler = (error) => {
    console.error("Caught error:", error);
    setError(error);
  };

  return (
    <>
      <ErrorBoundaryContext.Provider value={errorHandler}>
        {children}
      </ErrorBoundaryContext.Provider>
      <ErrorAlert error={error} onDismiss={() => setError(null)} />
    </>
  );
}

// context
const ErrorBoundaryContext = React.createContext(null);

// Custom hook
export function useErrorHandler() {
  return React.useContext(ErrorBoundaryContext);
}

for the unexpected errors which occurs while rendering a component, use the class component componentDidCatch(error, errorInfo) like below

class RenderErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Render error caught:", error, errorInfo);
    
    if (this.props.onError) {
      this.props.onError(error);
    }
  }

  render() {
    if (this.state.hasError) {
  return (
    <>
      {this.props.children}
      <ErrorAlert/>
    </>
  );
}

return this.props.children;
  }
}

and then in your app.js or any component, do this:

    function App() {
      const [error, setError] = useState(null);
      
      const errorHandler = (error) => {
        console.error("Error handled:", error);
        setError(error);
      };
    
      return (
          <RenderErrorBoundary onError={errorHandler}>
            <DashBoad/>
          </RenderErrorBoundary>
      );
    }

 - or you can combine the functional error handler provider with the
   component error handler like this :

    function GentleErrorBoundary({ children }) {
      const [error, setError] = useState(null);
      
      const errorHandler = (error) => {
        console.error("Error handled:", error);
        setError(error);
      };
    
      return (
        <ErrorBoundaryContext.Provider value={errorHandler}>
          <RenderErrorBoundary onError={errorHandler}>
            {children}
          </RenderErrorBoundary>
          <ErrorAlert error={error} onDismiss={() => setError(null)} />
        </ErrorBoundaryContext.Provider>
      );
    }

本文标签: javascriptPrevent Error Boundary from Replacing UI and Instead Show an AlertStack Overflow