解决方案:
使用错误边界:
import React, { Component } from 'react'
//错误边界
//https://zh-hans.reactjs.org/docs/error-boundaries.html#gatsby-focus-wrapper
export default class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error, errorInfo) {
// Catch errors in any components below and re-render with error message
this.setState({
error: error,
errorInfo: errorInfo
})
// You can also log error messages to an error reporting service here
}
render() {
if (this.state.errorInfo) {
// Error path
return (
<div className="m-error-wrap">
<div className="m-error-img-wrap">
<div className="m-error-img"></div>
</div>
<div className="m-error-text">网页出错了,请尝试刷新一下~</div>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
// Normally, just render children
return this.props.children;
}
}
在路由处使用错误边界:
import React, { Suspense, lazy } from 'react'
import { connect } from 'react-redux'
import {
Switch,
Route,
Redirect,
useHistory,
withRouter,
} from 'react-router-dom'
//自己开发的公共组件会再此处全部引入
import { ErrorBoundary, Loading } from '../components/light'
const Login = lazy(() => import('../views/light/login/Login'))
const SaleLogin = lazy(() => import('../views/sale/login/Login'))
const EduLogin = lazy(() => import('../views/edu/login/Login'))
const ProducerLogin = lazy(() => import('../views/producer/login/Login'))
const Index = lazy(() => import('../views/light/index/Index'))
const NotFound = lazy(() => import('../views/light/notFound/NotFound'))
function Router({ extraRouter }) {
window.reactRouter = useHistory()
return (
<>
<ErrorBoundary>
<Suspense fallback={<Loading isLazyLoading={true}></Loading>}>
<Switch>
<Redirect from="/" to="/light/login" exact></Redirect>
<Route path="/light/login" component={Login}></Route>
<Route path="/sale/login" component={SaleLogin}></Route>
<Route path="/edu/login" component={EduLogin}></Route>
<Route path="/producer/login" component={ProducerLogin}></Route>
<Route path="/light/index" component={Index}></Route>
<Route path="/sale/index" component={Index}></Route>
<Route path="/edu/index" component={Index}></Route>
<Route path="/producer/index" component={Index}></Route>
{extraRouter.toJS().map((item) => (
<Route
key={item.path}
path={item.path}
component={item.component}
></Route>
))}
<Route path="/404" component={NotFound}></Route>
<Redirect from="*" to="/404" exact></Redirect>
</Switch>
</Suspense>
</ErrorBoundary>
<Loading></Loading>
</>
)
}
const mapStateToProps = (state) => {
return {
extraRouter: state.getIn(['light', 'extraRouter']),
}
}
const mapDispatchToProps = (dispatch) => {
return {
onSetState(key, value) {
dispatch({ type: 'SET_LIGHT_STATE', key, value })
},
onDispatch(action) {
dispatch(action)
},
}
}
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Router))