Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应警告:无法对未安装的组件调用setState(或forceUpdate)_Javascript_Reactjs_Axios - Fatal编程技术网

Javascript 反应警告:无法对未安装的组件调用setState(或forceUpdate)

Javascript 反应警告:无法对未安装的组件调用setState(或forceUpdate),javascript,reactjs,axios,Javascript,Reactjs,Axios,我有两个部分: 订单-获取一些数据并显示。 ErrorHandler-如果服务器上发生错误,模式将显示并显示一条消息。 ErrorHandler组件正在扭曲order组件 我使用axios包在Orders组件中加载数据,我使用axios拦截器设置错误状态,并在卸载组件后弹出 当我来回导航到orders组件时,控制台中有时会出现错误: Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a

我有两个部分: 订单-获取一些数据并显示。 ErrorHandler-如果服务器上发生错误,模式将显示并显示一条消息。 ErrorHandler组件正在扭曲order组件

我使用axios包在Orders组件中加载数据,我使用axios拦截器设置错误状态,并在卸载组件后弹出

当我来回导航到orders组件时,控制台中有时会出现错误:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in Orders (at ErrorHandler.jsx:40)
    in Auxiliary (at ErrorHandler.jsx:34)
    in _class2 (created by Route)
我试图通过我以前的案例来解决这个问题,但在这里,我无法通过检查员制作axios代币。以前有人解决过这个问题吗

以下是我的组件: 订单:

错误处理程序:

import React, { Component } from 'react';
import Auxiliary from '../Auxiliary/Auxiliary';
import Modal from '../../components/UI/Modal/Modal';

const ErrorHandler = (WrappedComponent, api) => {
    return class extends Component {
        requestInterceptors = null;
        responseInterceptors = null;
        state = {
            error: null
        };

        componentWillMount() {
            this.requestInterceptors = api.interceptors.request.use(request => {
                this.setState({ error: null });
                return request;
            });
            this.responseInterceptors = api.interceptors.response.use(response => response, error => {
                this.setState({ error: error });
            });
        }

        componentWillUnmount() {
            api.interceptors.request.eject(this.requestInterceptors);
            api.interceptors.response.eject(this.responseInterceptors);
        }

        errorConfirmedHandler = () => {
            this.setState({ error: null });
        }

        render() {
            return (
                <Auxiliary>
                    <Modal
                        show={this.state.error}
                        modalClosed={this.errorConfirmedHandler}>
                        {this.state.error ? this.state.error.message : null}
                    </Modal>
                    <WrappedComponent {...this.props} />
                </Auxiliary>
            );
        }
    };
};

export default ErrorHandler;

无法在componentWillMount方法中设置状态。尝试重新考虑您的应用程序逻辑,并将其转移到另一个生命周期方法中。

您不能在componentWillMount方法中设置状态。尝试重新考虑您的应用程序逻辑,并将其转移到另一个生命周期方法中。

我认为这是由于触发设置状态的异步调用,即使组件未装入,也可能发生。要防止这种情况发生,可以使用某种标志:

  state = {
    isMounted: false
  }
  componentDidMount() {
      this.setState({isMounted: true})
  }
  componentWillUnmount(){
      this.state.isMounted = false
  }
然后在setState调用中使用if:

if (this.state.isMounted) {
   this.setState({ loading: false, orders: fetchedOrders });
}
编辑-添加功能组件示例:

function Component() {
  const [isMounted, setIsMounted] = React.useState(false);

  useEffect(() => {
    setIsMounted(true);
    return () => {
      setIsMounted(false);
    }
  }, []);

  return <div></div>;
}

export default Component;

我认为这是由于异步调用触发了setState,即使组件未装入,也可能发生这种情况。要防止这种情况发生,可以使用某种标志:

  state = {
    isMounted: false
  }
  componentDidMount() {
      this.setState({isMounted: true})
  }
  componentWillUnmount(){
      this.state.isMounted = false
  }
然后在setState调用中使用if:

if (this.state.isMounted) {
   this.setState({ loading: false, orders: fetchedOrders });
}
编辑-添加功能组件示例:

function Component() {
  const [isMounted, setIsMounted] = React.useState(false);

  useEffect(() => {
    setIsMounted(true);
    return () => {
      setIsMounted(false);
    }
  }, []);

  return <div></div>;
}

export default Component;

我认为根本原因与我昨天的回答相同,您需要在卸载时取消请求,我不知道您是否在为api.get call in Orders组件执行此操作

关于错误处理的说明,它看起来太复杂了,我肯定会鼓励查看React提供的。您不需要拦截器或更高阶组件

对于ErrorBounders,React引入了一个名为componentDidCatch的生命周期方法。 您可以使用它将ErrorHandler代码简化为:

class ErrorHandler extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true, errorMessage : error.message });
  }

  render() {
    if (this.state.hasError) {
      return <Modal 
                    modalClosed={() => console.log('What do you want user to do? Retry or go back? Use appropriate method logic as per your need.')}>
                    {this.state.errorMessage ? this.state.errorMessage : null}
                </Modal>
    }
    return this.props.children;
  }
}
并在代码中使用它作为:

<ErrorHandler>
   <Orders />
</ErrorHandler>

我认为根本原因与我昨天的回答相同,您需要在卸载时取消请求,我不知道您是否在为api.get call in Orders组件执行此操作

关于错误处理的说明,它看起来太复杂了,我肯定会鼓励查看React提供的。您不需要拦截器或更高阶组件

对于ErrorBounders,React引入了一个名为componentDidCatch的生命周期方法。 您可以使用它将ErrorHandler代码简化为:

class ErrorHandler extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true, errorMessage : error.message });
  }

  render() {
    if (this.state.hasError) {
      return <Modal 
                    modalClosed={() => console.log('What do you want user to do? Retry or go back? Use appropriate method logic as per your need.')}>
                    {this.state.errorMessage ? this.state.errorMessage : null}
                </Modal>
    }
    return this.props.children;
  }
}
并在代码中使用它作为:

<ErrorHandler>
   <Orders />
</ErrorHandler>


我没有在那里设置状态,我只是做了一个设置函数来设置状态,但是它会在之后发生。但我也尝试将其更改为componentDidMount,错误仍然存在。你确实在那里设置了状态。错误堆栈跟踪告诉你:我没有在那里设置状态,我只是做了一个设置函数来设置状态,但它会在之后发生。但我也尝试将其更改为componentDidMount,错误仍然存在。你确实在那里设置了状态。错误堆栈跟踪告诉您:使用ComponentDidMount没有帮助..有时仍然会出现错误…:创建一个React JSFIDLE,奇怪的是,相同的错误显示在componentDidMountuse ComponentDidMountWid上。有时仍然会出现错误…:创建一个React JSFIDLE,奇怪的是,React文档中的ComponentDidMount上显示了相同的错误:您不应该在componentWillUnmount中调用setState,因为组件永远不会被重新呈现。组件实例一旦卸载,就再也不会被装载了。对,错过了。。。我已经更新了虚拟示例,这不就是通过不设置状态从而破坏预期功能来消除错误吗?预期功能仅适用于已安装的组件。如果没有安装组件,则没有预期的功能。实际上,在这种情况下,唯一可行的解决方案就是这里介绍的解决方案。@Goran.it对于一个功能组件呢?来自react docs:您不应该在componentWillUnmount中调用setState,因为组件永远不会被重新呈现。组件实例一旦卸载,就再也不会被装载了。对,错过了。。。我已经更新了虚拟示例,这不就是通过不设置状态从而破坏预期功能来消除错误吗?预期功能仅适用于已安装的组件。如果没有安装组件,则没有预期的功能。实际上,在这种情况下,唯一可行的解决方案就是这里介绍的解决方案。@Goran.it对于一个功能组件来说呢?