React에서 useEffect를 사용할 때 의존성 배열안에 함수를 넣어주어야 하는 경우가 종종 있다. 예를들어 아래 코드를 살펴보자.


1. 코드 동작
위 코드는 모달을 띄울 때 3초가 지나면
handleRemovePlace
함수를 통해 모달을 자동으로 닫게 만드는 기능을 작성한 코드이다. DeleteConfirmation
컴포넌트에 prop으로 handleRemovePlace
함수를 전달해줘서 onConfirm
으로 사용할 수 있도록 하였다.여기서 의존성 배열안에
onConfirm
함수를 넣었다. 2. 문제점
이렇게 코드를 작성하면 생길 수 있는 문제점은
무한루프
에 빠질수 있다는 것이다.동작과정을 살펴보면 처음 모달이 띄어졌을 때 3초가 지나면
onConfirm
을 실행시켜 setModalIsOpen
을 false로 바꿔준다. 그렇게 되면 해당 함수가 있는 컴포넌트가 리렌더링이 되서 handleRemovePlace
라는 함수가 다시 새로 생성된다. 자바스크립트 동작에서 함수의 기능, 코드가 같더라도 다시 생성이 되면 다른 함수라고 취급을 받기 때문에 함수가 새롭게 바뀐다고 여겨진다.
따라서
useEffect
에 의존성배열에 들어있던 onConfirm
이 바뀌었다고 인지를 하고 또 onConfirm
을 실행한다. 그러므로 위 과정을 무한으로 반복하게 되는 버그가 발생할 수 있다.이런 버그를 발생시키지 않게 하려면 리렌더링이 되더라도 해당 함수가
재생성
되는 것이 아닌 재사용
이 되도록 만들어야 한다.3. 해결방법
이를 지원하는 React의 Hook이 있는데 바로
useCallback
이다.useCallbackuseCallback
은 리렌더링 간에 함수 정의를 캐싱해 주는 React Hook입니다.-React 공식 문서-

이런식으로 사용하면 해당 의존성 배열안에 값이 변경되지 않는한 이 함수는 리렌더링이 발생하더라도 항상 재사용이 된다. 이 방법을 통해 버그를 방지할 수 있겠다.