react "Maximum Update Depth Exceeded" Error 원인과 해결방법

홍준섭·2022년 9월 14일

react

목록 보기
10/29

원인 1: 함수에 대한 참조를 전달하는 대신 함수를 호출하는 경우

function App() {
  const [terms, setTerms] = useState(false);

  const acceptTerms = () => {
    setTerms(true);
  };

  return (
    <>
      <label>
        <input type="checkbox" onChange={acceptTerms()} /> Accept the Terms
      </label>
    </>
  );
}

렌더링 -> acceptTerms 즉시 호출 -> 리렌더링 -> acceptTerms 즉시 호출이 반복되어 무한 렌더 루프에 빠진다.

<input type="checkbox" onChange={acceptTerms} />

그렇기에 이러한 방식으로 변경해준다.

원인 2: useEffect의 종속성을 가진 변수를 useEffect안에서 업데이트 하는 경우

function App() {
  const [views, setViews] = useState(0);

  useEffect(() => {
    setViews(views + 1);
  }, [views]);

  return <>Some content</>;
}

위의 useEffect의 경우 view가 변할 때 실행 되는데 useEffect가 실행되면 view값이 변하고 view값이 변하면 useEffect가 실행되는 것이 반복되어 무한루프에 빠지게 된다.

useEffect(() =>{
	setViews((v) => v+1);
},[]);

이러한 형식으로 종속성 배엘에서 변수를 제거하거나

function App() {
  const [views, setViews] = useState(0);
  const [isInitialRender, setIsInitialRender] = useState(true);

  useEffect(() => {
    if (isInitialRender) {
      setIsInitialRender(false);
      setViews(v + 1);
    }
  }, [views, isInitialRender]);

  return <>Some content</>;
}

종속성 배열을 정리할 수 없는 경우 다시 실행할지 여부를 제한하는 추가 변수를 종속성 배열에 추가 하여 해결 할 수 있다.

원인 3: 컴포넌트 내부에 선언된 함수가 useEffect안에서 사용되는 경우

function App() {
  const [views, setViews] = useState(0);

  const incrementViews = () => {
    setViews((v) => v + 1);
  };

  useEffect(() => {
    incrementViews();
  }, [incrementViews]);

  return <>Some content</>;
}

incrementViews의 경우 모든 렌더에서 동일한 기능인 것처럼 보이지만 실제로는 각 렌더에서 메모리에 새로운 기능이 생성된다.

 useEffect(() => {
    const incrementViews = () => {
      setViews((v) => v + 1);
    };
    incrementViews();
  }, []);

따라서 함수 선언을 useEffect안으로 옮기거나

const incrementViews = useCallback(() => {
    setViews((v) => v + 1);
  }, []);

useCallback을 이용하여 종속성 배열의 변수가 변경되지 않는 한 새 함수를 생성하지 않게 한다.

profile
개발 공부중입니다

0개의 댓글