首页 > 解决方案 > 无法对未安装的组件执行 React 状态更新。表示内存泄漏

问题描述

我是反应的新手。我通过使用 axios 检索数据来显示反应顶点图表。我尝试了很多方法来卸载它,但无法找到正确的方法。它产生一个错误说。警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务。

如何卸载和取消所有订阅?

I have attached my code and the UI here below.
import React, {Component} from "react";
import GridWrapper from "../helpers/gridWrapper";
import Chart from 'react-apexcharts'
import ContentWrapper from "../helpers/contentWrapper";
import GridWrapperL from "../helpers/twoSideBySideWrapper/gridWrapperL";
import axios from "axios";


let source = axios.CancelToken.source();
export default class Charts extends Component{
 


  constructor(props) {
    super(props);
    this._isMount= false;
    this.state = {
      options: {
        chart: {
          id: 'apexchart-example'
        },
        xaxis: {
          categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999]
        }
      },
      series: [{
        name: '',
        data: [],
      },
      { name:"In progress stages",
      data:[],
  },

  { name:"Completed stages",
  data:[],
},
      // {
      //   name: 'Team B',
      //   data: [10, 70, 35, 55, 49, 80, 70, 55, 12]
      // },
    
    ]
    }
    source = axios.CancelToken.source();
  }

  
  async componentDidMount(){
    this._isMount=true;
    const salary=[]; const age=[]; const stages=[];

    //Getting projects details
      await axios.get('http://localhost:5000/api/projects',  {
        cancelToken: source.token
      }).then (Response=>{
        const data=[] = Response.data.projects; 
        var todo=0; var inprogress=0; var done=0;
        const emp_name=[]; const projectID=[]; const project_name=[]; 
        const todoARR=[] ; const inProgressArr=[]; const readyArr=[];
        

        //Checking conditions for each projects
        data.forEach(element => {
         // console.log(element._id);
          project_name.push(element.projectName);
          projectID.push(element._id);
        //  projectID.forEach(element =>{
            console.log("stage")
            
            axios.get(`http://localhost:5000/api/auth/stages/findproject/projectId?id=${element._id}` ,   {
              cancelToken: source.token
            }).then (Response2=>{
              const data2=Response2.data.stage;

              //Collecting information about the stages for each project
              data2.forEach(element2 => { 
            //  console.log(Response2, "HEY....................................")
              //console.log(element2.status + "HERE")
              if(element2.status == "TO-DO"){
                todo = todo+1;
              }
              if(element2.status == "IN-PROGRESS"){
             //   console.log("Yes")
                inprogress = inprogress+1;
              }
  
              if(element2.status == "READY"){
                done=done+1;
              }})
            
             // console.log(todo,inprogress,done);
              todoARR.push(todo);
              inProgressArr.push(inprogress);
              readyArr.push(done);
              todo=0; inprogress=0; done=0;
  
        
         });
  
      // console.log(stages)
       //console.log(project_name + "projects");
  
        })
//Setting Apex chart data
      console.log("salary", age);
      if(this._isMount){
      
      this.setState({
        options: {
          chart: {
            id: 'apexchart-example'
          },
          xaxis:{
            categories:project_name,
          }
        },
        series: [{
          name: 'Todo stages',
          data: todoARR,
        },
         { name:"In progress stages",
          data:inProgressArr,
      },

      { name:"Completed stages",
      data:readyArr,
  },
      ]
      
      })
    }
    })
    
    .catch(err =>{
      console.log("error", err)
    })

  }


  async componentWillUnmount() {
    this._isMounted = false;
    // this.setState({
    //   options: {
    //     chart: {
    //       id: 'apexchart-example'
    //     },
    //     xaxis:{
    //       categories:[1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999],
    //     }
    //   },
    //   series: [{
    //     name: '',
    //     data: [],
    //   }],
      

    
    
   // })
 }

 setState = (state, callback) => {
  if (this._isMount) {
    super.setState(state, callback);
  }
}
 
  render(){
  return(
 
        <center>
    <div>
     
      {/* We can change the type by simply typing "line" */}
      <Chart options={this.state.options} series={this.state.series} type="bar" width={1000} height={520} />
    </div>
    </center>
 
  );
  }
};

在此处输入图像描述

标签: reactjsasync-awaitaxios

解决方案


卸载组件后,您不会取消 axios 令牌;在您的 上componentWillUnmount,添加以下内容:

source.cancel("Component unmounted, request is cancelled.");

文档:https ://axios-http.com/docs/cancellation


推荐阅读