Resetting Error Boundary Error State
For bunpkg, I use a Wizard component to display a series of steps to generate UNPKG links.
When a request to Web API fails, an error is caught with an Error Boundary component and display an error message in ErrorBoundary.FallbackComponent (from react-error-boundary
, a simple but better implementation found on React documentation).
But the error boundary wasn't reset when a user moved onto a different step in the wizard.
I would like to share my failed attempt and the proper workaround to reset Error Boundary components.
But this can apply to your custom ErrorBoundary component.
😪 TL;DR
Update Error Boundary key props to let React reset the error state.
ℹ About Demo
The following demo has a component that randomly throws an error and the error boundary shows the error message caught.
Credit: the demo program is created by Brian Vaugn on CodeSandBox.

Error Boundary Reset Demo
🙅♂️ First attempt (bad workaround)
react-error-boundary provides only following props (leaving out children) and no way to clear the error caught.
FallbackComponent- A component to display in case of erroronError- A callback triggered on error
Following is how ErrorBoundary.render is implemented.
| render() { | |
| const {children, FallbackComponent} = this.props; | |
| const {error, info} = this.state; | |
| if (error !== null) { | |
| return ( | |
| <FallbackComponent | |
| componentStack={ | |
| info ? info.componentStack : '' | |
| } | |
| error={error} | |
| /> | |
| ); | |
| } | |
| return children; | |
| } |
FallbackComponent is displayed if an error exists.
So my first attempt was to create a reference (this.errorBoundary) and directly manipulate it as it is a 3rd party component.
Yes, stupid of me to even attempt to directly manipulate the state even without using setState...
| class Wizard extends Component { | |
| errorBoundary = React.createRef(); | |
| // redacted unrelevant code... | |
| onStepClick = current => { | |
| this.errorBoundary.current.state.error = null; | |
| }; | |
| render() { | |
| const { current } = this.state; | |
| return ( | |
| <div> | |
| <Steps current={current}> | |
| {steps.map((item, step) => ( | |
| <Steps.Step | |
| key={item.title} | |
| onClick={e => this.onStepClick(step)} | |
| /> | |
| ))} | |
| </Steps> | |
| <div className="steps-content"> | |
| <ErrorBoundary | |
| ref={this.errorBoundary} | |
| FallbackComponent={ErrorFallbackComponent} | |
| > | |
| {this.getContent()} | |
| </ErrorBoundary> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| } |
🙆 Proper Workaround
I knew that the workaround was just so hacky that I created a request ticket on react-error-boundary GitHub repository, requesting to provide a way/prop to clear the error.
And Brian has replied with a proper React-way of resetting error boundary - provide a key to an instance of ErrorBoundary component to reset the instant.error in the next render phase.
| class App extends React.Component { | |
| state = { | |
| errorBoundaryKey: 0 | |
| }; | |
| handleRerenderButtonClick = () => this.forceUpdate(); | |
| handleResetButtonClick = () => | |
| this.setState(prevState => ({ | |
| errorBoundaryKey: prevState.errorBoundaryKey + 1 | |
| })); | |
| render() { | |
| return ( | |
| <div className="App"> | |
| <button onClick={this.handleRerenderButtonClick}>re-render</button> | |
| <button onClick={this.handleResetButtonClick}> | |
| reset error boundary | |
| </button> | |
| <ErrorBoundary key={this.state.errorBoundaryKey}> | |
| <ComponentThatMayError /> | |
| </ErrorBoundary> | |
| </div> | |
| ); | |
| } | |
| } |
You can see that as you click on reset error boundary button, it updates the key on ErrorBoundary component (
<ErrorBoundary key={this.state.errorBoundaryKey}>) using handleResetButtonClick method, which will clear the internal error state by increasing errorBoundaryKey by one every time forcing a re-render.
😞 Failures
I was just too obsessed with "making things work" and overused Refs (even though ReactJS clearly recommends you not to).
Second of all, I didn't even consider using setState but directly manipulated the error state (this.errorBoundary.current.state.error = null).
👋 Parting Words
Many thanks to Brian for react-error-boundary, helping me realize the mistake and providing the workaround.
I hope the post help you should you run into the situation where an error boundary need to be reset & not go through the same bad practice/failures I mentioned above.
Lastly, Bunpkg uses the workaround suggested.
Webmentions
Loading counts...