Axios全局错误处理HOC无法弹出错误Modal且状态被重置问题排查
Axios错误处理高阶组件模态框无法显示问题
我实现了一个用于管理Axios错误的高阶组件,可将错误信息在Modal组件中展示。目前已能将错误存入错误处理程序的state中,但Modal无法正常显示,且错误状态很快就会被重置。
问题代码如下:
import Modal from "../../components/UI/Modal/Modal"; import { Component, Fragment } from "react"; import CSSModule from './withErrorHandler.module.css'; // 包装所有使用Axios的组件并处理其错误的高阶组件 const withErrorHandler = (WrappedComponent, axiosInstance) => { return class extends Component { state = { error: null } componentDidMount() { this.catchError(); } componentDidUpdate() { this.catchError(); } componentWillUnmount() { axiosInstance.interceptors.request.eject( this.reqInterceptor ); axiosInstance.interceptors.response.eject( this.resInterceptor ); } catchError() { // 重置之前的所有错误 this.reqInterceptor = axiosInstance.interceptors.request.use((request) => { this.setState({ error: null }); return request; }, (error) => { this.setState({ error: error }); }); // 接收响应时检查错误 this.resInterceptor = axiosInstance.interceptors.response.use(response => { console.log("[withErrorHandler], response:", response); return response; }, (error) => { console.log(error); this.setState({ error: error }); }); } displayError = () => { this.setState({ error: null }); } render() { console.log("[withErrorHandler], error: ", this.state.error); const error = this.state.error ? ( <Modal showModal = {!!this.state.error} displayModalHandler = {this.displayError}> <div className = {CSSModule.ErrorMessage}> {`ERROR: ${this.state.error.message}`} </div> </Modal> ) : null; console.log("error element", error); return( <Fragment> {error} <WrappedComponent {...this.props}/> </Fragment> ); } } }; export default withErrorHandler;
其中Modal组件接收以下props:
showModal- 布尔值,为true时展示模态框,为false时隐藏displayModalHandler- 点击模态框背景层时执行的函数
预期行为:发生错误时展示模态框。
实际行为:模态框未展示。
从控制台输出可以看到存入state的错误会被覆盖,但不清楚出现这一问题的原因。
问题已解决
修复方案为添加新旧状态的相等性校验,同时移除this.reqInterceptor的第二个参数,修复后代码如下:
const withErrorHandler = (WrappedComponent, axiosInstance) => { return class extends Component { state = { error: null } componentDidMount() { this.catchError(); } componentWillUnmount() { axiosInstance.interceptors.request.eject( this.reqInterceptor ); axiosInstance.interceptors.response.eject( this.resInterceptor ); } catchError() { // 重置之前的所有错误 this.reqInterceptor = axiosInstance.interceptors.request.use((request) => { if(this.state.error) this.setState({ error: null }); return request; }); // 接收响应时检查错误 this.resInterceptor = axiosInstance.interceptors.response.use(response => response, (error) => { console.log(error); if(!this.state.error) this.setState({ error: error }); }); } displayError = () => { this.setState({ error: null }); } render() { console.log("[withErrorHandler], error: ", this.state.error); const error = this.state.error ? ( <Modal showModal = {!!this.state.error} displayModalHandler = {this.displayError}> <div className = {CSSModule.ErrorMessage}> {`ERROR: ${this.state.error.message}`} </div> </Modal> ) : null; return( <Fragment> {error} <WrappedComponent {...this.props}/> </Fragment> ); } } };
内容的提问来源于stack exchange,提问作者gusti
相关产品推荐
相关产品推荐

