反应警告:无法在卸载的组件上调用setState(或forceUpdate) [英] React Warning: Can't call setState (or forceUpdate) on an unmounted component

查看:79
本文介绍了反应警告:无法在卸载的组件上调用setState(或forceUpdate)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个组件:

订单 - 获取一些数据并显示它。

ErrorHandler - 如果服务器上发生某些错误,模式将显示并显示消息。

ErrorHandler组件正在修改订单组件

I have 2 components:
Orders - fetch some data and display it.
ErrorHandler - In case some error happen on the server, a modal will show and display a message.
The ErrorHandler component is warrping the order component

我正在使用axios包来加载订单中的数据组件,我使用axios拦截器来设置有关错误的状态,并在卸载组件后弹出。

I'm using axios package to load the data in Orders component, and i use axios interceptors to setState about the error, and eject once the component unmounted.

当我向后和向前导航到订单组件时,我有时会收到错误在控制台中:

When i navigate to the orders components back and forward i sometimes get an error in the console:

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)

我试图通过我以前的案例解决它 React Warning:只能更新已安装或安装的组件,但在这里我无法通过检查员制作axios令牌。有没有人以前解决这个问题?

I tried to solve it by my previous case React Warning: Can only update a mounted or mounting component but here i can't make an axios token by the inspectors. Does anyone solve this issue before?

以下是我的组件:


订单:

Here are my components:

Orders:

import React, { Component } from 'react';
import api from '../../api/api';
import Order from '../../components/Order/Order/Order';
import ErrorHandler from '../../hoc/ErrorHandler/ErrorHandler';

class Orders extends Component {
    state = {
        orders: [],
        loading: true
    }

    componentDidMount() {
        api.get('/orders.json')
            .then(response => {
                const fetchedOrders = [];
                if (response && response.data) {
                    for (let key in response.data) {
                        fetchedOrders.push({
                            id: key,
                            ...response.data[key]
                        });
                    }
                }
                this.setState({ loading: false, orders: fetchedOrders });
            })
            .catch(error => {
                this.setState({ loading: false });
            });
    }

    render() {
        return (
            <div>
                {this.state.orders.map(order => {
                    return (<Order
                        key={order.id}
                        ingrediencies={order.ingrediencies}
                        price={order.price} />);
                })}
            </div>
        );
    }
}

export default ErrorHandler(Orders, api);

ErrorHandler:

ErrorHandler:

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;


推荐答案

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

I think that's due to asynchronous call which triggers the setState, it can happen even when the component isn't mounted. To prevent this from happening you can use some kind of flags :

  state = {
    isMounted: false
  }
  componentDidMount() {
      this.setState({isMounted: true})
  }
  componentWillUnmount(){
      this.state.isMounted = false
  }

然后用if封装你的setState调用:

And later wrap your setState calls with if:

if (this.state.isMounted) {
   this.setState({ loading: false, orders: fetchedOrders });
}

这篇关于反应警告:无法在卸载的组件上调用setState(或forceUpdate)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆