93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
|
interface ErrorBoundaryProps {
|
|
children: React.ReactNode;
|
|
fallback?: React.ReactNode;
|
|
}
|
|
|
|
interface ErrorBoundaryState {
|
|
hasError: boolean;
|
|
error?: Error;
|
|
}
|
|
|
|
const translations = {
|
|
error: 'Error',
|
|
issue: 'An issue occurred',
|
|
retry: 'Retry'
|
|
};
|
|
|
|
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
constructor(props: ErrorBoundaryProps) {
|
|
super(props);
|
|
this.state = { hasError: false };
|
|
}
|
|
|
|
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
|
return { hasError: true, error };
|
|
}
|
|
|
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
console.error('ErrorBoundary caught an error:', error, errorInfo);
|
|
}
|
|
|
|
handleRetry = () => {
|
|
this.setState({ hasError: false, error: undefined });
|
|
};
|
|
|
|
render() {
|
|
if (this.state.hasError) {
|
|
if (this.props.fallback) {
|
|
return this.props.fallback;
|
|
}
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text style={styles.title}>{translations.error}</Text>
|
|
<Text style={styles.error}>
|
|
{this.state.error?.message || translations.issue}
|
|
</Text>
|
|
<TouchableOpacity style={styles.retryButton} onPress={this.handleRetry}>
|
|
<Text style={styles.retryText}>{translations.retry}</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
padding: 20,
|
|
backgroundColor: '#fff',
|
|
},
|
|
title: {
|
|
fontSize: 18,
|
|
fontWeight: '600',
|
|
marginBottom: 10,
|
|
color: '#333',
|
|
},
|
|
error: {
|
|
color: '#ff4d4f',
|
|
marginBottom: 20,
|
|
textAlign: 'center',
|
|
},
|
|
retryButton: {
|
|
backgroundColor: '#1890ff',
|
|
paddingHorizontal: 20,
|
|
paddingVertical: 10,
|
|
borderRadius: 4,
|
|
},
|
|
retryText: {
|
|
color: '#fff',
|
|
fontSize: 16,
|
|
},
|
|
});
|
|
|
|
export default ErrorBoundary;
|