react-native-cn-richtext-editor
Version:
RichText Editor for React-Native
95 lines • 3.56 kB
JavaScript
import React from 'react';
import { NativeModules, StyleSheet, Text, View } from 'react-native';
import { getAppLoadingLifecycleEmitter } from './AppLoading';
const { ExponentAppLoadingManager } = NativeModules;
async function finishedAsync() {
if (ExponentAppLoadingManager && ExponentAppLoadingManager.finishedAsync) {
return await ExponentAppLoadingManager.finishedAsync();
}
}
export default class RootErrorBoundary extends React.Component {
constructor() {
super(...arguments);
this.state = {
error: null,
};
this._appLoadingIsMounted = false;
this._subscribeToGlobalErrors = () => {
this._appLoadingIsMounted = true;
// Bacon: This isn't supported in RNWeb yet
let ErrorUtils = global.ErrorUtils;
if (!ErrorUtils)
return;
let originalErrorHandler = ErrorUtils.getGlobalHandler();
ErrorUtils.setGlobalHandler((error, isFatal) => {
if (this._appLoadingIsMounted) {
finishedAsync();
if (isFatal) {
this.setState({ error });
}
}
originalErrorHandler(error, isFatal);
});
};
this._unsubscribeFromGlobalErrors = () => {
// We don't remove the global error handler that we set here because it is conceivable that the
// user may add error handlers *after* we subscribe, and we don't want to override those, so
// instead we just gate the call
this._appLoadingIsMounted = false;
};
}
componentWillMount() {
// In production the app will just hard crash on errors, unless the developer decides to handle
// them by overriding the global error handler and swallowing the error, in which case they are
// responsible for determining how to recover from this state.
if (__DEV__) {
getAppLoadingLifecycleEmitter().once('componentDidMount', this._subscribeToGlobalErrors);
getAppLoadingLifecycleEmitter().once('componentWillUnmount', this._unsubscribeFromGlobalErrors);
}
}
// Test this by adding `throw new Error('example')` to your root component
componentDidCatch(error) {
if (this._appLoadingIsMounted) {
finishedAsync();
this.setState({ error });
}
console.error(error);
}
render() {
if (this.state.error) {
return (<View style={styles.container}>
<Text style={styles.warningIcon}>⚠️</Text>
<Text style={[styles.paragraph, { color: '#000' }]}>
A fatal error was encountered while rendering the root component.
</Text>
<Text style={styles.paragraph}>
Review your application logs for more information, and reload the app when the issue is
resolved. In production, your app would have crashed.
</Text>
</View>);
}
else {
return this.props.children;
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
paragraph: {
marginBottom: 10,
textAlign: 'center',
marginHorizontal: 30,
maxWidth: 350,
fontSize: 15,
color: '#888',
},
warningIcon: {
fontSize: 40,
marginBottom: 20,
},
});
//# sourceMappingURL=RootErrorBoundary.js.map