reactjs - react 内存泄漏,componentDidUnmount 不工作

标签 reactjs memory fetch

我查看了许多试图解决此问题的帖子,并尝试了多种方法来处理此错误,但我仍然找不到答案。我知道这是一个常见问题,但我对 React 的理解似乎不足以解决问题。我正在尝试消除此错误:

无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请取消 componentWillUnmount 方法中的所有订阅和异步任务。

我无法理解为什么 componentWillUnmount 没有解决它。这是代码:

import React from 'react';
import ReactDOM from 'react-dom';

export class PracticeData extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      data: [],
      isLoaded: false,
    }
}
componentDidMount() {
  this.mounted=true;
  fetch('https://jsonplaceholder.typicode.com/users')
  .then(res => res.json())
  .then(json => {
    this.setState({   //triggers a rendering cycle
      isLoaded: true,
      data: json,
    })
  });
} 
componentWillUnmount(){
  this.isLoaded=false;
}
  render(){
    var { isLoaded, data } = this.state;
      if(!isLoaded) {
        return <div>Loading...</div>
      } else {
       return (
         <div className="container-fluid">
           <div className="row">{
             data.map(data => <div key={data.id}>
               <div className="list">
                 <li className="header">{data.name}</li>
               <div className="body">  
                 <li><strong>Company:</strong> {data.company.name}</li>
                 <li><strong>User Name: </strong> {data.username}</li>
                 <li><strong>Email: </strong> {data.email}</li>
                 <li><strong>Phone: </strong>{data.phone}</li>
               </div>
                 <li className="address"><strong>Address: </strong></li>
               <div className="body">
                 <li><strong>Street:</strong> {data.address.street}</li>
                 <li><strong>Suite: </strong> {data.address.suite}</li>
                 <li><strong>City: </strong> {data.address.city}<br/></li>
                 <li><strong>Zip Code:</strong> {data.address.zipcode}</li>
               </div>   
               </div>
               </div>
              )}
           </div>
          </div>
        );
      }
    }
  }
ReactDOM.render(<PracticeData/>, document.getElementById('root'));

最佳答案

抓取看起来是组件卸载后唯一可能解析的东西,为此你需要一个 AbortController .

基本用法是

const controller = new AbortController();
const { signal } = controller;

fetch(url, { signal })

稍后如果需要,您可以中止获取

controller.abort()

更新您的组件

export class PracticeData extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      data: [],
      isLoaded: false,
    }
  }

  controller = new AbortController();

  componentDidMount() {
    this.mounted=true;
    const { signal } = this.controller;

    fetch('https://jsonplaceholder.typicode.com/users', { signal }) // <-- pass signal in fetch options
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoaded: true,
          data: json,
        })
      })
      // catch any rejected fetch promises (including aborted fetches!)
      .catch(console.error);
  }

  componentWillUnmount(){
    this.isLoaded=false;
    this.controller.abort(); // <-- abort any in-flight fetch requests
  }
...

Edit cancel fetch request on unmount

注意: fetch 通常只返回因网络错误而被拒绝的 Promise,valis HTML 错误响应将在已解决的 Promise 中返回。如评论中所述,中止的提取也将返回拒绝。

关于reactjs - react 内存泄漏,componentDidUnmount 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61844919/

相关文章:

javascript - 如何在React js中使用map函数获取嵌套循环值?

python - 如何使用 python 在内存中查找 00000000 就像 C 使用 while != 00000000 的方式

java - Activity onDestroy 在 OutOfMemoryError 之前从未被调用过

javascript - 如何使用 fetch 将 FormData 从 javascript 发送到 ASP.NET Core 2.1 Web API

php - Zend Framework 1. 获取评论

php - 检查文件(robots.txt,favicon.ico)到网站 php

javascript - React Native Typescript babel-plugin-module-resolver 错误 : Cannot find module or its corresponding type declerations

javascript - npm-EPERM mkdir : operation not permitted on Windows

c++ - 我是否应该始终使用 shared_ptr 来创建类实例(而不是仅仅使用 new)?

reactjs - 防止 FullCalendar (React) 在每次渲染时重新获取事件和资源