Replies: 1 comment
-
|
Here's an attempt at an error boundary whose key only changes after an error has occurred (i.e. not on every URL change): https://gist.github.com/donaldpipowitch/1248ca4658506c7c8b481edfbd740ca7 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Take this minimal app with lazy-loading per route:
The
ErrorBoundarycomponent is a class-based error boundary, keeping some boolean flag state that's turned on when there was an error. This includes lazy-loading errors (i.e. the chunk fetch failed).The problem is that the way reconciliation works, the error boundary will be shared across all sibling routes inside a certain parent
Routes. So the inner state of this ever-lasting error boundary is not reset when you switch to other views.My first instinct, trying to be clever, was to put a single error boundary around it all, and have it use the
useLocation().keyas itskeyprop. That way, you'd get a new error boundary every time you switch views. However, this soon proves being an issue. This makes your app re-mount views that should not be unmounted and mounted again. For instance, a mere change in the query params of a view re-mounts the entire view. Switching to theuseLocation().pathnameinstead of thekeymight improve that particular scenario, but it still re-mounts onpathnamechanges that are not really switching to another view.So the only remaining alternative I see is manually applying a key per error boundary:
This, however, becomes repetitive and verbose pretty soon. Not to mention error-prone. So the next step would be to make a helper to reuse this pattern.
You'd think you could make a
MyAppRoutesort of component wrapping theRoutecomponent, but that's a no-go. TheRoutescomponent requires that its children must be exclusivelyRouteelements (ref). So your only choice is to move away from jsx and create a helper function that is not meant to be called as a React component, but directly instead:Which you would use like this:
Much better for this simpler example. But it still can become inconvenient or unidiomatic when your
Routeelements also requirechildren.So the question is: is this the only way? Or am I missing something and there's a better way to make this work while keeping the ergonomics and the idiomatic use of React and JSX more intact than the direction on which I'm going?
Beta Was this translation helpful? Give feedback.
All reactions