ReactJS UseEffect Ошибка утечки памяти - что ее вызывает? - PullRequest
0 голосов
/ 31 марта 2020

Это мой первый проект с использованием React Hooks. Сегодня я столкнулся с проблемой утечки памяти - мое приложение выдает мне эту ошибку:

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

Я исследовал некоторые решения. Например, я мог бы отслеживать состояние моего компонента, используя переменную isMounted.

Единственная проблема в том, что я не совсем уверен, где бы я это реализовал. Например, у меня есть 3 UseEffect хуков в одном из моих компонентов. Этот конкретный компонент, среди прочего, связан с ошибкой утечки памяти.

UseEffect 1:

 useEffect(() => {
    socket.on("allLobbyClients", clients => {
      if (readyList.length == clients.length) {
        socket.emit("gameStarting", activeGamePin);
        socket.on("gameStartingMsg", data => {
          updateGameStarting(data);
        });
        setTimeout(() => {
          navigate("/game-draw", true);
        }, 5000);
      }
    });
  }, [readyList]);

UseEffect 2:

  useEffect(() => {
    socket.on("readyClientIndexes", indexes => {
      updateReadyList(indexes);
    });
  }, []);

UseEffect 3:

useEffect(() => {
    socket.emit("joinRoom", activeGamePin);
    socket.emit("getClientsForLobby", activeGamePin);
    socket.on("allLobbyClients", data => {
      //Gets the 'Client Index', which can be used to identify them in the <ol> when they specify they are ready to start the game.
      let clientName = window.localStorage.getItem("clientName");
      updateClientIndex(data.indexOf(clientName));
      let activePlayers = data.map((client, index) => (
        <li
          id={index}
          key={index}
          className={readyList.includes(index) ? "ready" : "unready"}
        >
          {client}
        </li>
      ));
      updateClientList(activePlayers);
    });
  }, [readyList]);

У меня также есть функция, которая использует Ax ios для выполнения запроса POST.

  function playerIsReady() {
    let gamePin = activeGamePin;
    axios
      .post(`${backend}/newIndex`, {
        clientIndex: clientIndex,
        gamePin: gamePin
      })
      .then(response => {
        console.log(response.data);
      });
    setTimeout(() => {
      socket.emit("playerReady", gamePin);
    }, 2000);
    socket.on("readyClientIndexes", indexes => {
      updateReadyList(indexes);
      updateReadyBtn("invisible");
    });
  }

Мой основной вопрос: откуда вероятна ошибка утечки памяти? Происходит ли это от одного из моих хуков useEffect ИЛИ от функции Ax ios? Впервые за какое-то время я чувствую себя совершенно беспомощным в поиске решения.

Любые ответы очень, очень ценятся - заранее спасибо!

PS Я подозреваю, что ошибка связан с функцией Ax ios, потому что в компоненте моего приложения произошли ошибки утечки памяти, которые НЕ используют хук UseEffect. Следовательно, я застрял!

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Не запуская код, я мог бы посмотреть на всю работу сокетов. Вы настраиваете их для выполнения работы, но нет ничего, что могло бы их отключить после размонтирования компонента. Попробуйте очистить их в функции, которую вы можете вернуть из useEffect.

1 голос
/ 31 марта 2020

Я бы сказал, что вам нужно отписаться от подписки socket. Обычно это делается в useEffect функции очистки (return () => {...})

Обновление

Как только вы внедрили isMounted, добавьте условную проверку перед каждым местом, где вы устанавливаете состояние asyn c: isMounted && setSomeState(..)

...