Maximum update depth exceeded. ...

Hyunwoo Seo·2022년 7월 10일
0

ErrorCode

목록 보기
10/16
post-thumbnail
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

Maximum update depth exceeded. 을 해결하는 방법중 하나인 useCallback 사용하기


사용법

const memoizedCallback = useCallback(() => { 
    doSomething(a, b); 
}, [a, b]);

//두 번째 인수로 전달된 배열의 값들이 변경되지 않았다면, 메모이제이션된 콜백(첫 번째 인수)를 반환한다.

maximum update depth exceeded 에러가 나타나는 예시.

import React, { useState, useEffect } from 'react'; 
const Counter = () => { 
    const [count, setCount] = useState(0); 
    const incrementCount = () => { 
        setCount((count) => count + 1); 
    } 
    useEffect(() => { 
        incrementCount(); 
    }, [incrementCount]); 
    return <>Content</>
}; 
export default Counter;

Counter 컴포넌트는 리렌더링될때마다 새로운 incrementCount 함수를 만들게 되고, useEffect 애서 새로운 참조값을 받기 때문에 effect내의 incrementCount 함수를 실행하게 된다. 따라서 Maximum update depth exceeded. 에러를 볼 수 있다.

문제가 "Counter 컴포넌트가 리렌더링될 때마다 incrementCount 함수를 새로 만들어 useEffect 내부의 effect가 계속 실행되는 것"임을 알 수 있다.

따라서 incrementCount 가 새로 만들어지지 않는 두 가지 방법을 통해 Maximum update depth exceeded. 가 일어나지 않도록 한다.


  1. useEffect

    useEffect 내부로 함수를 옮겨 매번 새로운 함수를 만드는 것을 막을 수 있다.

    import React, { useState, useEffect } from 'react'; 
    const Counter = () => { 
        const [count, setCount] = useState(0); 
        useEffect(() => { 
            const incrementCount = () => { 
                setCount((count) => count + 1); 
            } 
            incrementCount(); 
        }, []); 
        return <>Content</>
    }; 
    
    export default Counter;
    
    //useEffect 내부에서 함수가 생성되었기 때문에, 두번째 인자가 빈배열이므로 마운트 후 한번만 실행된다.
  1. useCallback

    메모이제이션된 incrementCount 를 사용하기 위해 useCallback 을 사용한다.

    import React, { useState, useEffect, useCallback } from 'react';
    
    const Counter = () => { 
        const [count, setCount] = useState(0); 
        const incrementCount = useCallback(() => { 
            setCount((count) => count + 1); 
        }, []); 
        useEffect(() => { 
            incrementCount(); 
        }, [incrementCount]); 
        return ( 
            <div>
            	<p>You clicked {count} times</p> 
    			<button onClick={incrementCount}> Click me </button> 
    		</div> 
    	) 
    };
    
    //useCallback 의 두 번째 인수인 배열에서 수정된 값이 없으므로 incrementCount 함수를 새로 생성하지 않는다.

이러한 문제들은 useEffect dependency 에 부적절한 값이 들어가 발생한다.

임의로 인수로 전달한 값이 변경되지 않도록 하거나, 적절한 값을 넣어야 해결된다.

그래서 나는 주로 함수를 useEffect 에 넣을 때, dependency array 안에 함수를 직접넣기보다는, 함수안에 들어가는 파라미터 등을 dependency 값으로 넣는다.

0개의 댓글