useEffect() 사용시 메모리누수

Siwoo Pak·2021년 8월 21일
1

React

목록 보기
13/14

useEffect()에 fetch() 사용하는 일반적인 코드

import React, {useEffect, useState} from 'react';

export default function App() {
  const [Data, setData] = useState(null);
  
  useEffect(() => {
    const fetchData = async() => {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const newData = await response.json();
      setData(newData);
    }
    fetchData();
  },[]);
}
  • useEffect()를 이용하여 한번만 실행하여 state에 저장하는 코드지만 에러가 발생

"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."

  • [Data]를 넣어도 동일한 에러 발생
  • 원인:
    • 요청이 늦게 올 떼, 컴포넌트가 unmount되어 요청이 대기중인 상태에 발생하는 에러.

해결

import React, {useEffect, useState} from 'react';

export default function App() {
  const [Data, setData] = useState(null);
  
  useEffect(() => {
    let isCleanUp = true;
    const fetchData = async() => {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const newData = await response.json();
      if(isCleanUp) setData(newData);
    }
    fetchData();
    return () => isCleanUp = false;
  },[]);
}
  • 더 확실한 방법은 http fetch를 취소하는 AbortController를 사용하는 것.
```js
import React, {useEffect, useState} from 'react';

export default function App() {
  const [Data, setData] = useState(null);

  useEffect(() => {
    let abortController = new AbortController();
    (async () => {
      try {
        const response = await fetch(
          "https://jsonplaceholder.typicode.com/todos/1",
          {
            signal: abortController.signal,
          }
        );
        const newData = await response.json();
        setData(newData);
      } catch (err) {
        if (err.name === "AbortError") console.log(err);
      }
    })();
    return () => abortController.abort();
  }, []);
}
profile
'하루를 참고 인내하면 열흘을 벌 수 있고 사흘을 참고 견디면 30일을, 30일을 견디면 3년을 벌 수 있다.'

0개의 댓글