[React] useEffect 내 무한루프 원인 (Error Maximum Update depth exceeded)
배경
김뉴비는 사내 관리자페이지를 React, Redux-saga로 만들기로 했다. 천천히 학습시간을 갖고 개발하면 좋았겠지만, 시간이 부족해 개발부터하고 버그를 수정하며 React를 알아가는 중이다.
원하던 기능
DB에서 type별로 최신 컨텐츠 목록을 조회해서 store에 담는 것
(아래 코드는 예제를 위해 변형한 것입니다.)
const ContentListContainer = () => {
const type = 'help';
const dispatch = useDispatch();
const {list, error, loading} = useSelector((contentList) => ({
list: contentList.list,
error: contentList.error,
}));
useEffect(() => {
dispatch(getContentList(type));
}, [dispatch]);
return ...
};
import client from './client';
export const getContentList = (type) => {
if (!type)
throw new Error("getContentList type is falsy");
return client.get(`/${type}`);
};
코드 설명
- useSelector를 통해 store에서 관리 중인 contentList 객체를 찾는다. (최초에는 초기화된 상태임)
-- store -- contentList : { list : null, error : null }
- useEffect에서 getContentList 액션 함수를 호출한다. 조회된 DB 데이터 contentList 객체에 update 한다.
-- store -- contentList : { list : {...}, error : null }
에러 발생
Error: Maximum update depth exceeded 발생
console과 서버 로그를 보니 GET API가 미친듯이 날라가고 있음
원인
useEffect()
는 랜더링이 초기화된 후 실행된다. 이때 line 10에서 getContentList()
라는 Action을 dispatch(실행)시킨다.
getContentList()
는 DB의 데이터를 조회해서 store에 있는 contentList
를 Update하는데, 이 때 트리거가 발생하면서 컴포넌트가 리랜더링된다 (ㅎㅎㅎ)
컴포넌트가 리랜더링 되면서 다시 useEffect()
를 호출하고 getContentList()
Action이 실행된다.
예제 코드와 이미지의 명이 일치하지 않는다. 정확히 알고 싶다면 아래 원문글을 참고하길 바란다.
원문 : medium.com/@andrewmyint/infinite-loop-inside-useeffect-react-hooks-6748de62871
해결
useEffect()
가 초기화 시점과 store의 state가 변경되었을 때에만 실행되도록 변경한다.
useEffect()
의 두번째 파라미터에 type
을 넘겨서, 최초 랜더링때와 type
값이 변경되었을 때에만 컴포넌트를 리랜더링 하도록 한다.
const ContentListContainer = () => {
const type = 'help';
const dispatch = useDispatch();
const {list, error, loading} = useSelector((contentList) => ({
list: contentList.list,
error: contentList.error,
}));
useEffect(() => {
dispatch(getContentList(type));
}, [dispatch, type]);
return ...
};
느낀 점
아... 웬만하면 프레임워크에 대해 모르는 상태로 개발을 해도 성능 이슈가 크게 발생하지 않는데, 리액트는 좀 공부하고 개발을 하는 게 좋겠다는 생각이 든다.
'Programming > JavaScript&Frameworks' 카테고리의 다른 글
JavaScript 새로운 Null 처리 방법 - Optional chaining(?.) & Nullish coalescing operator(??) (0) | 2019.12.16 |
---|---|
자바스크립트는 정말 싱글스레드일까? (9) | 2019.12.09 |
댓글
이 글 공유하기
다른 글
-
JavaScript 새로운 Null 처리 방법 - Optional chaining(?.) & Nullish coalescing operator(??)
JavaScript 새로운 Null 처리 방법 - Optional chaining(?.) & Nullish coalescing operator(??)
2019.12.16 -
자바스크립트는 정말 싱글스레드일까?
자바스크립트는 정말 싱글스레드일까?
2019.12.09