μ—λŸ¬

[React] memory leak error (useEffect cleanup function)__Can't perform a React state update on an unmounted component.

Minhhk 2024. 2. 27. 14:42
πŸ“Œ 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ν›… μ•ˆμ—μ„œ 클린업 ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜μ—¬, μ»΄ν¬λ„ŒνŠΈκ°€ μ–Έλ§ˆμš΄νŠΈλ˜κΈ° 전에 ν•„μš”ν•œ 정리 μž‘μ—…!

→ dataFetching 이후 μƒνƒœ μ—…λ°μ΄νŠΈλ₯Ό ν•˜κΈ° 전에 μ»΄ν¬λ„ŒνŠΈκ°€ μ—¬μ „νžˆ 마운트된 μƒνƒœμΈμ§€λ₯Ό ν™•μΈν•˜λŠ” λ°©λ²•μœΌλ‘œ 문제 ν•΄κ²°

 

 

이전 μ½”λ“œ

const MSearch = () => {
  const { searchText } = useParams();
  const axiosAuth = useAxiosAuth();
  const [data, setData] = useState([]);
  const [results, setResults] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    if (searchText !== '') {
      const searchRule = async () => {
        setIsLoading(true);
        const response = await axiosAuth({
          method: 'POST',
          url: '/api/~~~',
          data: { searchText },
        });
        setData(response.data);
        setResults(response.data);
        setIsLoading(false);
      };
      searchRule();
    }
  }, [searchText]);

  return ( ... )
}

 

 

 

λ³€κ²½ 된 μ½”λ“œ

const MSearch = () => {
  const { searchText } = useParams();
  const axiosAuth = useAxiosAuth();
  const [data, setData] = useState([]);
  const [results, setResults] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    // 마운트 μƒνƒœλ₯Ό μΆ”μ ν•˜λŠ” λ³€μˆ˜
    let isMounted = true;

    if (searchText !== '') {
      const searchRule = async () => {
        setIsLoading(true);
        try {
          const response = await axiosAuth({
            method: 'POST',
            url: '/api/~~~',
            data: { searchText },
          });
          if (isMounted) { // 마운트된 μƒνƒœ -> μ—…λ°μ΄νŠΈ
            setData(response.data);
            setResults(response.data);
            setIsLoading(false);
          }
        } catch (error) {
          console.error(error);
          if (isMounted) { // 마운트된 μƒνƒœ -> μ—λŸ¬
            setIsLoading(false);
          }
        }
      };
      searchRule();
    }

    // + 클린업 ν•¨μˆ˜,,, 마운트 μƒνƒœ false
    return () => {
      isMounted = false;
    };
  }, [searchText]);

  return ( ... )
};

 

>>

 

React의 useEffect 훅을 μ‚¬μš©ν•  λ•Œ, 클린업(clean-up) ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜μ—¬ 비동기 μž‘μ—…μ΄λ‚˜ ꡬ독을 정리할 수 μžˆλ‹€.

이것은 μ»΄ν¬λ„ŒνŠΈκ°€ μ–Έλ§ˆμš΄νŠΈλ˜κ±°λ‚˜ μž¬λžœλ”λ§λ˜κΈ° 전에 μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λœλ‹€.

 

일반적으둜 useEffect ν›… μ•ˆμ—μ„œ 비동기 μž‘μ—…μ„ μˆ˜ν–‰ν•  λ•Œ, ν•΄λ‹Ή μž‘μ—…μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό ν΄λ‘œμ €λ‚˜ μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœμ— μ €μž₯ν•œλ‹€. 그러면 비동기 μž‘μ—…μ΄ μ™„λ£Œλœ 후에 μ»΄ν¬λ„ŒνŠΈκ°€ μ–Έλ§ˆμš΄νŠΈλ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜κ³ , μ–Έλ§ˆμš΄νŠΈλ˜μ—ˆλ‹€λ©΄ μž‘μ—…μ„ μ€‘μ§€ν•˜κ±°λ‚˜ 정리할 수 μžˆλ‹€.

 

예λ₯Ό λ“€μ–΄, useEffect λ‚΄μ—μ„œ setInterval을 μ‚¬μš©ν•˜μ—¬ 일정 μ‹œκ°„λ§ˆλ‹€ μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•  λ•Œ, μ»΄ν¬λ„ŒνŠΈκ°€ μ–Έλ§ˆμš΄νŠΈλ˜λ©΄ ν•΄λ‹Ή setInterval을 클리어(clear)ν•΄μ•Ό ν•œλ‹€.

 

클린업 ν•¨μˆ˜λŠ” useEffect ν›…μ˜ λ°˜ν™˜ κ°’μœΌλ‘œ μ •μ˜λ˜λ©°, useEffect λ‚΄μ—μ„œ 클린업 ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ 마운트 ν•΄μ œλ  λ•Œ 호좜되며, 클린업 ν•¨μˆ˜κ°€ 호좜되면 이전에 μ„€μ •ν•œ λͺ¨λ“  μž‘μ—…μ„ 정리할 수 μžˆλ‹€.

 

예λ₯Ό λ“€μ–΄, useEffect λ‚΄μ—μ„œ ꡬ독을 μ„€μ •ν•œ 경우, 클린업 ν•¨μˆ˜μ—μ„œ ν•΄λ‹Ή ꡬ독을 해지할 수 μžˆλ‹€. 이것은 λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•˜κ³ , μ»΄ν¬λ„ŒνŠΈκ°€ 마운트 ν•΄μ œλ  λ•Œ λΆˆν•„μš”ν•œ μž‘μ—…μ΄λ‚˜ ꡬ독이 남지 μ•Šλ„λ‘ ν•œλ‹€.

 

정리 > useEffect λ‚΄μ—μ„œ setInterval을 μ‚¬μš©ν•˜μ—¬ 일정 μ‹œκ°„λ§ˆλ‹€ μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•  λ•Œ,

μ»΄ν¬λ„ŒνŠΈκ°€ μ–Έλ§ˆμš΄νŠΈλ˜λ©΄ ν•΄λ‹Ή setInterval을 클리어 ν•΄μ•Όν•˜λŠ” 것과 같은 λ§₯락이닀.