useEffect 사용 시 메모리 누수 문제

메론맛캔디·2021년 11월 1일
4
post-custom-banner

fetch뒤에 바로 setState를 하면 메모리 누수 문제가 생길 수 있다.
만약 서버에서 응답이 오는 시간이 길어지는 사이에 사용자가 다른 작업을 하면 컴포넌트가 unmount될 수 있다. 이때 컴포넌트는 사라지지만 요청은 여전히 대기 중일 것이다. 그리고 요청이 도착하고 setState에 값을 업데이트 하려고할 때 아래와 같은 메모리 누수와 관련한 경고가 뜰 수 있다.

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.

따라서 컴포넌트가 unmount가 될 경우에 요청이 늦게와도 조건문으로 setState를 업데이트하는 것을 방지할 수 있다.

const [userInfo, setUserInfo] = useState([]);
const [reviewInfo, setReviewInfo] = useState([]);
const [likesInfo, setLikesInfo] = useState([]);

useEffect(() => {
  let isComponentMounted = true;
  const fetchData = async () => {
        const userData = await axios.get(
          `${process.env.REACT_APP_API_URL}/users`
        );
        const likesData = await axios.get(
          `${process.env.REACT_APP_API_URL}/likes`
        );
        const reviewData = await axios.get(
          `${process.env.REACT_APP_API_URL}/reviews`
        );
        if (isComponentMounted) {
          setUserInfo(userData.data.data);
          setLikesInfo(likesData.data.data);
          setReviewInfo(reviewData.data.data);
        }
      };
      fetchData();

      return () => {
        isComponentMounted = false;
      };
  }, []);

또는 http fetch 요청을 취소하는 AbortController를 사용할 수 있다. AbortControllerfetch작업을 취소할 수있도록 해주는 인터페이스다.

axios 요청을 취소하는 건 아래와 같이 진행된다. 하지만 위와 동일하게 mount되었는지 안되어있는지를 변수에 두어서 따로 확인해야한다.

//useEffect안에 넣어주고
let unmounted = false;
let source = axios.CancelToken.source();

//cleanup에 cancel을 넣어준다.
unmounted = true;
source.cancel("Cancelling in cleanup");

정리

unmounted (마운트 해제)는 요청이 취소되지 않았거나 일부 다른 작업을 취소할 수 없는 경우 필요하다.
네트워크 호출이 반환되기 전에 네트워크 속도를 늦추고 구성 요소를 마운트 해제하면 unmounted된 컴포넌트에 대해 상태를 업데이트할 수 없다는 오류가 뜨는 것이다.
변수로 마운트가 되었는지 아닌지 관리해주면서 setState를 업데이트 해야지 위와 같은 오류를 막을 수 있다.



참고

https://stackoverflow.com/questions/53861916/canceling-an-axios-rest-call-in-react-hooks-useeffects-cleanup-failing/53878045

https://yceffort.kr/2021/02/memory-leak-and-useeffect

post-custom-banner

0개의 댓글