I'm not quite sure, if I fully understand the concept of React ErrorBoundary.
I need to say, that I actually want to start using the ErrorBoundary, but I'm using it for the first time.
So I created an ErrorBoundary component:
import React, { Component } from "react";
import * as Data from '../../backend/data';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, stackTrace) {
this.setState({ hasError: true });
console.log(error, stackTrace);
// Send error to backend
Data.trackError(error, stackTrace.componentStack, this.props.component, this.props.location, this.props.guestLandingPage?.identifier_token, this.props.user?.id);
}
render() {
if (this.state.hasError) {
return this.props.fallbackUI;
}
return this.props.children;
}
}
export default ErrorBoundary;
Now I tried to using it in my app.container.js (I will not copy the whole code of it, just the neccessary parts of it):
...
import NavBarComponent from './components/navbar.component';
import ErrorBoundary from './components/error/error.component';
import FallbackUI from './components/error/standardFallback.component';
...
class App extends Component {
...
render() {
const View = this.importView();
return (
<ErrorBoundary
location={"builder"}
component={"app.container.js"}
user={this.props.user}
fallbackUI={<FallbackUI />}
>
<Wrap>
<NavBarComponent
key={"navBarComponent"}
/>
...
</Wrap>
...
</ErrorBoundary>
)
}
}
Then I started to create manually an error. I added a variable in my navbar.component.js which is not existing and lead to throw an error.
That works fine so far. The error is being send to the backend and my fallback UI component is displayed. So far, so good.
Now, however, I did not want to catch the error at the top level, but in the individual components, so that the app is still available and an error message is only displayed in individual components in case of an error.
Therefore, I have now moved the ErrorBoundary component to navbar.component.js (and deleted it from app.container.js).
class NavBarComponent extends Component {
...
render() {
return (
<ErrorBoundary
location={"builder"}
component={"navbar.component.js"}
user={this.props.user}
fallbackUI={<FallbackUI />}
>
<Nav className="navbar navbar-expand-lg navbar-light">
...
</Nav>
</ErrorBoundary>
);
}
}
...expecting the same result, but showing my fallback UI component only where the navbar is displayed. But actually the result is, that the ErrorBoundary is not being fired at all when moved to navbar.
Why? Is it not possible to add the ErrorBoundary component to each component itself, so that only the component with the error will not be displayed and not the whole app?
PS: I was also wondering, why I could not use both getDerivedStateFromError and componentDidCatch method in my ErrorBoundary component. When defined getDerivedStateFromError method in ErrorBoundary, the method componentDidCatch was never called:
static getDerivedStateFromError(error) {
return { hasError: true };
}
...but as far as I can see, it works fine with just using componentDidCatch.