2020-01-06 TIL
January 06, 2020
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;
}, [])
- 해당 페이지가 mount 되면 isMount는 true가 된다.
- 비동기로 데이터를 요청한다.
- 데이터를 받아오는 도중 다른페이지로 넘어가게 되면 cleanup 함수가 실행된다.
- isMount가 false가 된다.
- 이때 데이터가 도착하면 isMount가 false이므로 받아온 데이터를 제거한다
예) A식당에 자리가 없어서 예약을 하고 다른 식당들을 둘러보고 있었다. 돌아다니다가 B식당 음식이 맛있어보여 B식당에 들어가 음식을 주문했다. 이 때 A식당에서 자리가 났다고 연락이 왔다. 하지만 이미 B식당에서 먹고있었기 떄문에 A식당의 예약을 취소했다. 이렇게 예약을 취소하는 행동을 cleanup함수에서 처리해준다고 생각하면 쉽다.
5FS
Facts
- 약수의 합 알고리즘 문제 풀이
- 리펙토링 오류 해결
- 검색기능 리펙토링 중
Feelings
Findings
- 오래 앉아있던거에 비해 결과물이 잘 안나온것같다. 피곤해서 그런것 같다. 일찍 자야겠다.
- useEffect에 대해서 잘 알고 있는줄 알았는데 처음보는 기능을 찾았다.
Future Action Plan
- 에러 해결할 때 마다 notion에 기록해두기
Feedback