For bunpkg, I use a Wizard component to display a series of steps to generate UNPKGlinks.
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.

🙅♂️ 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 error -
onError
– 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.
The post Resetting Error Boundary Error State appeared first on Sung's Technical Blog.
Top comments (0)