[React] useEffect 무한루프 문제 (Maximum update depth exceeded... )

Hyeon·2023년 5월 2일
0

React

목록 보기
1/1

며칠 전 겪은 따끈따끈한 오류...!

태초에 이런 코드가 있었다.

import { create } from "zustand";

const useListStore = create((set) => ({
  list: undefined,
  setList(list) {
    set({ list });
  },
}));

const useSetList = (prop) => { //(1)
  const listStore = useListStore(); 

  useEffect(() => {
    listStore.setList(prop);
        return () => { //(3)
      listStore.setList(undefined);
    };
  }, []); //(2)
};

const showList = () => {
    const { data } = useSWR(...생략...);
	useSetList(data?.map((v)=>{생략...})); 
}

원래 썼던 코드를 짧게 수정한 버전이라 코드가 좀 어색하다.
여튼 위 코드를 짧게 설명하자면 다음과 같다.

(1) useSetList는 매개변수로 들어온 prop를 setList에 넣어줌으로서 전역변수인 list를 업데이트 시키는 함수다.
(2) setList를 useEffect안에서 하고 있고, 두번째 인수인 배열에 빈배열을 넣었기 때문에 컴포넌트가 처음 마운트 될때만 위 함수가 호출된다.
(3) useEffect안에 return이 있기 때문에 컴포넌트가 언마운트 될 때 list를 undefined로 만든다.
(4) showList 함수에선 이런 useSetList에 data의 map한 값을 넣어서 (원하는 data 형태가 있었음) 전역변수인 list의 값을 설정해주고 있었다.

저 코드 자체에는 문제가 없었다. 문제가 발생한 건 data의 값이 바뀔 때마다(mutate할때마다) list를 set해주고 싶어서 useEffect의 의존성 배열에 prop 변수를 넣었을 때였다.

const useSetList = (prop) => { //(1)
  const listStore = useListStore(); 

  useEffect(() => {
    listStore.setList(prop);
        return () => { 
      listStore.setList(undefined);
    };
  }, [prop]); //오류의 시작
};

넣자마자 미친듯이 useEffect가 호출되더니 제목과 같은 오류가 떴다.

오류를 여러번 검색해봤지만 나와 같은 케이스의 오류는 잘 보이지 않았고...

그렇게 문제는 미궁으로 빠지는 듯 했지만... 사실 정말 별 것 아닌 이유 때문에 생긴 문제였다.

바로
useSetList(data?.map({...생략...})) 이 부분 때문이었다. map함수는 항상 새로운 배열을 리턴한다는 게 문제였다. useSetList 안에 useEffect의 의존성 배열에 prop을 넣어주는 순간, 들어오는 값이 바뀔때마다 useEffect는 호출된다.

고로... map함수는 새로운 배열을 만들어냈고, prop이 바뀌었기 때문에 호출된 useEffect는 열심히 setList를 해주고... list가 바뀐 것으로 인해 리렌더링 되니까 map함수가 또 호출되는, 이런 무한 굴레를 돌게 된 것...(으로 추측...)

어쨌든 이 문제는 useMemo를 사용해서 해결했다.

  const lists = useMemo(
    () =>
      data?.map((v) => ({...생략...})),
    [data]
  );
  
  useSetList(lists);

useSetList 부분에 인자를 useMemo를 사용해 만든 lists로 보내주면 된다! 이러면 data가 바뀔때만 list에 값이 들어가고, 매번 새로운 배열이 만들어지지 않기 때문에 무한루프에서 빠져나올 수 있다!

공부를 더 열심히 해야겠다...

profile
어 왜 되지? 에 대한 고찰

0개의 댓글