All you need is ErrorBoundary, the preferred way is to set up a HOC(Higher-order component) that can handle errors and prevent the app being crashed. You can also create ErrorBoundary component. Here is an example of HOC that might help you.
import React, { Component } from 'react';
export const withErrorBoundary = WrappedComponent => (
class extends Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch = (error, errorInfo) => catchFunc(error, errorInfo, this)
render() {
if (this.state.errorInfo) {
return handleError(this)
}
// Normal, just render children
return <WrappedComponent {...this.props} />;
}
}
);
const catchFunc = (error, errorInfo, ctx) => {
// catch errors in any components below and re-render with error message
ctx.setState({
error: error,
errorInfo: errorInfo
})
// log error messages, etc.
}
const handleError = (ctx) => (
// Error path
<div style={ctx.props.style || styles.error}>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{ctx.state.error && ctx.state.error.toString()}
<br />
{ctx.state.errorInfo.componentStack}
</details>
</div>
);
const styles = {
error: {
backgroundColor: '#f98e7e',
borderTop: '1px solid #777',
borderBottom: '1px solid #777',
padding: '12px',
}
}
export default withErrorBoundary;
Here, the withErrorBoundry is a higher-order component responsible to capture any error in wrapped component through componentDidCatch. All you need to do is just export your component with error boundary HOC and it will take care of the underlying error. Here is the example usage.
import React from 'react';
import { Text } from 'react-native';
import withErrorBoundary from './withErrorBoundary';
const ExampleComponent = (props) => (
<Text>{ props.user.name }</Text>
);
export default withErrorBoundary(ExampleComponent);
Alternatively, You can also create an ErrorBoundary component but using HOC is much simpler as compared to the ErrorBoundary component.
Cons
Error boundaries do not catch errors for,
- Event handlers
- Async code (e.g. setTimeout or requestAnimationFrame callbacks)
- Server-side rendering
- Errors are thrown in the error boundary itself
At this point you'll need to wrap error-prone code to try-catch block and throw Exceprion from catch block which will be further handled by outer HOC. Read more at official docs