2020-01-06 TIL

React

useEffect(() => {
    getCategories().then(value => {
        setProductsCategoryArr(Object.entries(value));
    });
}, [])

에러 : 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.

해결하기

  • mount : DOM이 생성되고 브라우저상에 나타나는 것
  • unmount : 브라우저에서 사라지는 것
  • unmount 상태인 컴포넌트에서 setState를 수행하려고 해서 생기는 문제이다. useEffect에서 async 작업을 취소하라고 한다. useEffect에 전달된 함수는 화면에 rendering이 완료된 후에 수행합니다.
  • useEffect는 컴포넌트가 화면에서 제거될 때 정리해야하는 리소스를 만듭니다.(구독, 타이머ID) 이것을 수행하기 위해서 useEffect로 전달된 함수는 정리(clean-up)함수를 반환할 수 있습니다. 정리함수는 메모리 누수 방지를 위해서 UI에서 컴포넌트를 제거하기 전에 수행됩니다
  • 컴포넌트가 언마운트되기 전이나, 업데이트 되기 직전에 어떠한 작업을 수행하고 싶다면 useEffect에서 뒷정리 함수를 반환해주어야 합니다.
  • useEffect에서 반환하는 함수를 뒷정리 함수라고 합니다. useEffect에 대한 뒷정리를 해준다고 이해하면 되는데
useEffect(() => {
    let isMount = true;
    getCategories().then(value => {
        if (isMount) {
            setProductsCategoryArr(Object.entries(value));
        }
    });

    return () => isMount = false;
}, [])
  1. 해당 페이지가 mount 되면 isMount는 true가 된다.
  2. 비동기로 데이터를 요청한다.
  3. 데이터를 받아오는 도중 다른페이지로 넘어가게 되면 cleanup 함수가 실행된다.
  4. isMount가 false가 된다.
  5. 이때 데이터가 도착하면 isMount가 false이므로 받아온 데이터를 제거한다

예) A식당에 자리가 없어서 예약을 하고 다른 식당들을 둘러보고 있었다. 돌아다니다가 B식당 음식이 맛있어보여 B식당에 들어가 음식을 주문했다. 이 때 A식당에서 자리가 났다고 연락이 왔다. 하지만 이미 B식당에서 먹고있었기 떄문에 A식당의 예약을 취소했다. 이렇게 예약을 취소하는 행동을 cleanup함수에서 처리해준다고 생각하면 쉽다.

5FS

Facts

  • 약수의 합 알고리즘 문제 풀이
  • 리펙토링 오류 해결
  • 검색기능 리펙토링 중

Feelings

  • 만족스러운 결과물이 나왔나?

Findings

  • 오래 앉아있던거에 비해 결과물이 잘 안나온것같다. 피곤해서 그런것 같다. 일찍 자야겠다.
  • useEffect에 대해서 잘 알고 있는줄 알았는데 처음보는 기능을 찾았다.

Future Action Plan

  • 에러 해결할 때 마다 notion에 기록해두기

Feedback


Park Answer

Find answer in the record