- 新增文章添加页面,支持文章基本信息、设置、高级设置和图片上传 - 新增经销商申请页面,支持申请信息填写和审核状态显示 - 新增用户地址添加页面,支持地址信息填写和地址识别功能 - 新增礼物添加页面,功能与文章添加类似 - 统一使用 .tsx 文件格式 - 添加 .editorconfig、.eslintrc 和 .gitignore 文件,规范代码风格和项目结构
125 lines
3.6 KiB
TypeScript
125 lines
3.6 KiB
TypeScript
import React, { Component, ReactNode } from 'react';
|
||
import Taro from '@tarojs/taro';
|
||
import { View, Text, Button } from '@tarojs/components';
|
||
import './ErrorBoundary.scss';
|
||
|
||
interface ErrorBoundaryState {
|
||
hasError: boolean;
|
||
error?: Error;
|
||
errorInfo?: React.ErrorInfo;
|
||
}
|
||
|
||
interface ErrorBoundaryProps {
|
||
children: ReactNode;
|
||
fallback?: ReactNode;
|
||
onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
|
||
}
|
||
|
||
/**
|
||
* 全局错误边界组件
|
||
* 用于捕获React组件树中的JavaScript错误
|
||
*/
|
||
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
||
constructor(props: ErrorBoundaryProps) {
|
||
super(props);
|
||
this.state = { hasError: false };
|
||
}
|
||
|
||
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
||
// 更新state,下次渲染将显示错误UI
|
||
return { hasError: true, error };
|
||
}
|
||
|
||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||
// 记录错误信息
|
||
this.setState({
|
||
error,
|
||
errorInfo
|
||
});
|
||
|
||
// 调用外部错误处理函数
|
||
if (this.props.onError) {
|
||
this.props.onError(error, errorInfo);
|
||
}
|
||
|
||
// 上报错误到监控系统
|
||
this.reportError(error, errorInfo);
|
||
}
|
||
|
||
// 上报错误到监控系统
|
||
private reportError = (error: Error, errorInfo: React.ErrorInfo) => {
|
||
try {
|
||
// 这里可以集成错误监控服务,如Sentry、Bugsnag等
|
||
console.error('ErrorBoundary caught an error:', error, errorInfo);
|
||
|
||
// 可以发送到后端日志系统
|
||
// this.sendErrorToServer(error, errorInfo);
|
||
} catch (reportError) {
|
||
console.error('Failed to report error:', reportError);
|
||
}
|
||
};
|
||
|
||
// 重置错误状态
|
||
private handleReset = () => {
|
||
this.setState({ hasError: false, error: undefined, errorInfo: undefined });
|
||
};
|
||
|
||
// 重新加载页面
|
||
private handleReload = () => {
|
||
Taro.reLaunch({ url: '/pages/index/index' });
|
||
};
|
||
|
||
render() {
|
||
if (this.state.hasError) {
|
||
// 如果有自定义的fallback UI,使用它
|
||
if (this.props.fallback) {
|
||
return this.props.fallback;
|
||
}
|
||
|
||
// 默认的错误UI
|
||
return (
|
||
<View className="error-boundary">
|
||
<View className="error-boundary__container">
|
||
<View className="error-boundary__icon">😵</View>
|
||
<Text className="error-boundary__title">页面出现了问题</Text>
|
||
<Text className="error-boundary__message">
|
||
抱歉,页面遇到了一些技术问题,请尝试刷新页面或返回首页
|
||
</Text>
|
||
|
||
{process.env.NODE_ENV === 'development' && (
|
||
<View className="error-boundary__details">
|
||
<Text className="error-boundary__error-title">错误详情:</Text>
|
||
<Text className="error-boundary__error-message">
|
||
{this.state.error?.message}
|
||
</Text>
|
||
<Text className="error-boundary__error-stack">
|
||
{this.state.error?.stack}
|
||
</Text>
|
||
</View>
|
||
)}
|
||
|
||
<View className="error-boundary__actions">
|
||
<Button
|
||
className="error-boundary__button error-boundary__button--primary"
|
||
onClick={this.handleReset}
|
||
>
|
||
重试
|
||
</Button>
|
||
<Button
|
||
className="error-boundary__button error-boundary__button--secondary"
|
||
onClick={this.handleReload}
|
||
>
|
||
返回首页
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
return this.props.children;
|
||
}
|
||
}
|
||
|
||
export default ErrorBoundary;
|