Предупреждение. Невозможно выполнить обновление состояния React для несмонтированного компонента. Это не работает, но указывает на утечку памяти в вашем приложении

Я пытаюсь создать приложение для реагирования, в котором я извлекаю данные через API, который отлично работает в течение нескольких секунд, а затем я получаю пустой экран и ошибку в консоли, которая выглядит следующим образом:

Консоль : это ошибка консоли браузера

Warning: Can't perform a React state update 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 a useEffect cleanup function.

CountryWise.js: это мой компонент, в котором я выполняю все операции.

import React, { useEffect, useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";

const CountryWise = () => {
  const [data, setData] = useState([]);
  const [name, setName] = useState("pakistan");
  const getCovidData = async () => {
    const res = await fetch(
      `https://api.covid19api.com/live/country/${name}/status/confirmed`
    );
    const actualData = await res.json();
    setData(actualData);
  };

  getCovidData();

  return (
    <>
      <div className = "container-fluid mt-5">
        <div className = "main-heading">
          <h1 className = "mb-5 text-center">Covid-19 Tracker</h1>
          <br />
          <select
            value = {name}
            onChange = {(event) => {
              setName(event.target.value);
            }}
          >
            <option value = "pakistan">Pakistan</option>
            <option value = "afghanistan">Afghanistan</option>
          </select>
        </div>

        <div className = "table-responsive">
          <table className = "table table-hover">
            <thead className = "table-dark">
              <tr>
                <th>Country</th>
                <th>Date</th>
                <th>Active Cases</th>
                <th>Confirmed Cases</th>
                <th>Deaths</th>
                <th>Recovered</th>
              </tr>
            </thead>
            <tbody>
              {data.map((curElm, ind) => {
                return (
                  <tr key = {ind}>
                    <th>{curElm.Country}</th>
                    <td>{curElm.Date}</td>
                    <td>{curElm.Active}</td>
                    <td>{curElm.Confirmed}</td>
                    <td>{curElm.Deaths}</td>
                    <td>{curElm.Recovered}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
};

export default CountryWise;

App.js: это мое приложение, в котором я визуализирую свой компонент CountryWise.js.

import React from "react";
import CountryWise from "./components/countryWiseData/Countrywise";

function App() {
  return <CountryWise />;
}

export default App;

index.js: вот мой файл index.js, в котором я визуализирую компонент приложения.

Вы получите бесконечный цикл, потому что каждый раз, когда вы вызываете getCovidData();, вы вызываете getCovidData, что заставляет CountryWise снова запускать свое тело, что затем вызывает getCovidData() и т. д. Когда ваш компонент размонтируется, ваша выборка все еще происходит в background, и когда он завершается, вызывается setData(), даже если ваш компонент уже размонтирован

Nick Parsons 06.04.2022 14:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
46
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Существует довольно распространенный хук под названием useIsMounted, который решает эту проблему (для функциональных компонентов)...

import { useRef, useEffect } from 'react';

export function useIsMounted() {
  const isMounted = useRef(false);

  useEffect(() => {
    isMounted.current = true;
    return () => isMounted.current = false;
  }, []);

  return isMounted;
}

затем в вашем функциональном компоненте

function Book() {
  const isMounted = useIsMounted();
  ...

  useEffect(() => {
    asyncOperation().then(data => {
      if (isMounted.current) { setState(data); }
    })
  });
  ...
}

useIsMounted позволит вам изменить state только до того, как компонент будет unmounted из DOM.

Ответ принят как подходящий

Замените getCovidData() этим кодом

 useEffect(() => {
            getCovidData()
        }, [name])

Другие вопросы по теме