What would be the cleanest way to wrap all screens managed by react-navigation in an error boundary that can also navigate. My current approach involves a top level component like:
class App extends Component{
navigateTo(routeName) {
this.navigator && this.navigator.dispatch(NavigationActions.navigate({ routeName }));
}
render(){
return (
<Provider store={store}>
<PersistGate persistor={persistor}>
<MenuProvider>
<ErrorBoundary navigateTo={this.navigateTo.bind(this)}>
<AppNavigator
ref={navigator=> {
NavigationService.setTopLevelNavigator(navigator);
this.navigator = navigator;
}}
/>
</ErrorBoundary>
</MenuProvider>
</PersistGate>
</Provider>
)
}
}
with a rather standard ErrorBoundary:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null, info: null };
}
componentDidCatch(error, info) {
this.setState({error, info});
this.props.navigateTo('SomeScreen');
}
render() {
if (this.state.error) {
return (
<Container>
<Content>
<Text> Got error: {JSON.stringify(this.state.error)}, info {JSON.stringify(this.state.info)} </Text>
</Content>
</Container>
)
}
return this.props.children;
}
}
However when an error occurs the navigator gets unmounted and ref is called again with null.
Alternatively, is there a way to have an ErrorBoundary as a descendant of AppNavigator that catches errors from any screen and can also access the navigator, eventually through a NavigationService?
you should be able to do this with custom navigators, below is an example with the new react-navigation V3 createAppContainer api as per, https://reactnavigation.org/docs/en/custom-navigators.html.
We have just implemented a revision in our app to achieve this when upgrading to V3.
That way your AppNavigator will still be mounted when the error boundary hits and will have access to your navigation props.
const StackNavigator = createStackNavigator({..});
class AppNavigator extends React.Component {
static router = StackNavigator.router;
render() {
const { navigation } = this.props;
return (
<ErrorBoundary navigation={navigation}>
<StackNavigator navigation={navigation} />
</ErrorBoundary>
);
}
}
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With