β—οΈπŸ“š μ—λŸ¬λ…ΈνŠΈ - Can't perform a React state update on an unmounted component

κΉ€μ˜€κ·ΌΒ·2020λ…„ 2μ›” 5일
30

μ—λŸ¬λ…ΈνŠΈ

λͺ©λ‘ 보기
1/2

μ—λŸ¬λ°œμƒ

λ¦¬μ•‘νŠΈλ₯Ό μ΄μš©ν•˜μ—¬ λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό 개발 ν•˜λ˜μ€‘ λ‹€μŒκ³Ό 같은 μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€λ‹€.

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.

κ²½κ³ ! μ–Έλ§ˆμš΄ν‹°λ“œλœ μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•΄μ„œλŠ” μƒνƒœ μ—…λ°μ΄νŠΈλ₯Ό μˆ˜ν–‰ν•  수 μ—†λ‹€.
ν•΄λ‹Ή μž‘μ—…μ€ μˆ˜ν–‰λ˜μ§€ μ•Šμ§€λ§Œ λ©”λͺ¨λ¦¬ λˆ„μˆ˜κ°€ λ°œμƒλœλ‹€.
ν•΄κ²°λ°©λ²•μœΌλ‘œ useEffect의 cleanup function을 μ΄μš©ν•΄λΌ

μ½˜μ†”μ°½μ— λΉ¨κ°„κΈ€μ”¨λ‘œ κ²½κ³  메세지가 λ‚˜μ˜€λ©΄ 항상 😑짜증이 λ‚˜μ§€λ§Œ μΉœμ ˆν•˜κ²Œ μ—λŸ¬ 메세지 μ†μ—λŠ” 해결방법을 μ•Œλ €μ€€λ‹€.

ν•΄λ‹Ή μ—λŸ¬κ°€ λ°œμƒν•œ 상황은 비동기 μž‘μ—…μ„ μ²˜λ¦¬ν•˜λŠ” κ³Όμ •μ—μ„œ λ°œμƒν•˜μ˜€λ‹€. 비동기 μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° 전에 loadingμ΄λΌλŠ” μƒνƒœλ³€μˆ˜λ₯Ό true둜 λ³€κ²½ν•˜μ—¬ ν˜„μž¬ λ‘œλ”©μ€‘μ΄λΌλŠ” λͺ¨μŠ΅μ„ λ³΄μ—¬μ£Όμ—ˆκ³  비동기 μž‘μ—…μ΄ μ™„λ£Œλœ 경우 λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈκ°€ 사라지고 loadingμ΄λΌλŠ” μƒνƒœλ³€μˆ˜λ₯Ό false둜 λ³€κ²½ν•˜μ˜€λ‹€. 이 κ³Όμ •μ—μ„œ μœ„μ™€ 같은 μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€λ‹€. λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈκ°€ 사라진 μ΄ν›„μ˜€κΈ° 떄문에 loading μƒνƒœλ³€μˆ˜λ₯Ό κ΄€λ¦¬ν•˜λ˜ μ»΄ν¬λ„ŒνŠΈκ°€ μ‚¬λΌμ‘ŒκΈ° λ•Œλ¬Έμ— μƒνƒœλ³€μˆ˜λ₯Ό μ—…λ°μ΄νŠΈ ν•  수 μ—†λ‹€λŠ” μ—λŸ¬μ˜€λ‹€. λ¬Όλ‘  μ»΄ν¬λ„ŒνŠΈκ°€ 사라지면 ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈκ°€ κ΄€λ¦¬ν•˜λ˜ λͺ¨λ“  μƒνƒœλ³€μˆ˜λŠ” 처음으둜 λŒμ•„κ°€κΈ° λ•Œλ¬Έμ— loadingμ΄λΌλŠ” μƒνƒœλ³€μˆ˜λ₯Ό false둜 ꡳ이 λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„ 되기 λ•Œλ¬Έμ— μƒνƒœλ³€μˆ˜λ₯Ό false둜 바꾸지 μ•Šμ•„λ„ λ˜μ§€λ§Œ false둜 λ°”κΎΈκ³  싢은 경우 μ–΄λ–»κ²Œ ν•΄μ•Όν•˜λŠ”μ§€ μ•Œκ³  μ‹Άμ—ˆλ‹€.

μ—λŸ¬μ½”λ“œ

μ—λŸ¬κ°€ λ°œμƒν•œ 상황을 κ°„λž΅ν•œ μ½”λ“œλ‘œ μž‘μ„±ν•΄ λ³΄μ•˜λ‹€.

App.js

import React, { useState } from "react";
import "./App.css";
import Modal from "./Modal";

const App = () => {
  const [visible, setVisible] = useState(false);

  const onClick = () => {
    setVisible(true);
  };

  return (
    <div className="App-container">
      {visible && <Modal setVisible={setVisible} />}
      <button className="App-modal-button" onClick={onClick}>
        λͺ¨λ‹¬
      </button>
    </div>
  );
};

export default App;

Modal.js

import React, { useState, useEffect } from "react";
import "./Modal.css";

const Modal = ({ setVisible }) => {
  const [loading, setLoading] = useState(false);

  const threeSecods = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("success");
      }, 3000);
    });
  };

  const onClick = () => {
    setLoading(true);
    threeSecods()
      .then(res => {
        if (res === "success") {
          setVisible(false);
        }
      })
      .then(() => setLoading(false));
  };

  return (
    <div className="modal-back">
      <div className="modal-container">
        {loading && <span>Loading...</span>}
        <button className="modal-close" onClick={onClick}>
          λ‹«κΈ°
        </button>
      </div>
    </div>
  );
};

export default Modal;

해결방법

1) κ°€μž₯ κ°„λ‹¨ν•œ ν•΄κ²°λ°©λ²•μœΌλ‘œλŠ” λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈκ°€ μ‚¬λΌμ§€λŠ” μ‹œμ  이전에 loadingμ΄λΌλŠ” λ³€μˆ˜λ₯Ό false둜 λ³€κ²½ν•˜κ³  λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬λΌμ§€κ²Œ ν•˜λŠ” 것이닀.

const onClick = () => {
  setLoading(true);
  threeSecods().then(res => {
    if (res === "success") {
      setLoading(false); // λ‘œλ”© μƒνƒœλ³€μˆ˜ λ³€κ²½
      setVisible(false); // λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈ μ’…λ£Œ
    }
  });
};

2) λ‹€μŒ λ°©λ²•μœΌλ‘œλŠ” μ½˜μ†”μ°½μ—μ„œ μ•Œλ €μ€€ λ°©λ²•μœΌλ‘œ useEffect의 cleanup function을 μ΄μš©ν•˜λŠ” 것이닀.

const onClick = () => {
  setLoading(true);
  threeSecods().then(res => {
    if (res === "success") {
      setVisible(false);
    }
  });
};

useEffect(() => {
  return () => setLoading(false); // cleanup function을 이용
}, []);

κ²°λ‘ 

μ–΄λ–»κ²Œ μƒκ°ν•˜λ©΄ κ°„λ‹¨ν•œ 였λ₯˜μ§€λ§Œ μ»΄ν¬λ„ŒνŠΈ μƒνƒœκ°’μ„ μ²˜λ¦¬ν•˜λŠ” κ³Όμ •μ—μ„œ λˆ„κ΅¬λ“ μ§€ μ‰½κ²Œ λ°œμƒν•  수 μžˆλŠ” μ—λŸ¬λΌκ³  μƒκ°ν•˜μ˜€λ‹€.

profile
πŸ‘¨πŸ»β€πŸ’» 우린 닡을 찾을 것이닀. 늘 κ·Έλž¬λ“―μ΄(ꡬ글링을 ν†΅ν•΄μ„œ)

3개의 λŒ“κΈ€

comment-user-thumbnail
2020λ…„ 8μ›” 7일

도움 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!!

1개의 λ‹΅κΈ€
comment-user-thumbnail
2020λ…„ 12μ›” 30일

λͺ‡μΌ κ°„ κ³ μƒν–ˆλŠ”λ° 덕뢄에 힌트λ₯Ό μ–»μ—ˆμŠ΅λ‹ˆλ‹€! κ°μ‚¬ν•©λ‹ˆλ‹€:)

λ‹΅κΈ€ 달기