-
[Hooks] useCallback과 React.memo개발/React 2021. 3. 2. 22:09
재사용이라는 관점에서 useCallback은 useMemo와 비슷하다. useMemo는 추가한 deps가 바뀌지 않으면 함수를 호출하지 않고 기존 값을 사용하게 하는 것이고, useCallback은 deps가 변경될 때만 함수를 새로 생성하게 해준다. 보통은 컴포넌트가 re-render될 때마다 함수가 새롭게 만들어진다. 성능 최적화를 할 때 useCallback을 쓰는데, 최적화가 가능한 컴포넌트에 잘 써야 하며 모든 컴포넌트가 최적화가 필요한 것은 아니다. 최적화를 하기 위해서 코드가 추가되어야 하기 때문이다. useCallback만으로는 최적화가 끝나지 않는다. React.memo와 같이 써야 한다. 컴포넌트 re-render를 최적화 할 때, 함수가 매번 새로 생성되면 최적화가 일어나지 않으므로 useCallback을 사용해 함수를 재사용할 수 있게 해야 한다.
위와 같은 페이지가 있다고 가정해보자. 계정명과 이메일에 값을 입력할 때마다 onChange 함수가 호출된다. onChange는 부모 컴포넌트에 있으며 onChange를 통해 변경되는 값 역시 부모 컴포넌트에 있는 state이기 때문에 onChange 함수가 호출될 때마다 re-render가 일어난다. 등록 버튼을 누르기 전까지 계정 목록은 re-render가 필요가 없다. 이를 확인하기 위해 크롬 웹스토어에서 react dev tool를 설치해 'Highlit updates when components render' 항목을 체크하면 쉽게 확인할 수 있다. 버그가 있는지 re-render 되지 않아도 하이라이트 되는 경우가 종종 있기 때문에 낌새가 이상하면 콘솔에 로그를 찍어보자.
props가 변경될 때만 re- render가 발생하게 하기 위해서, 계정을 출력하고 있는 UserList 컴포넌트와 User 컴포넌트를 React.memo() 함수의 인자로 넣어서 내보낸다.
export하지 않은 컴포넌트의 경우, 컴포넌트 전체를 감싸 객체에 담은 뒤 해당 객체를 컴포넌트 사용하듯 사용하면 된다.
등록과 삭제 버튼, 그리고 계정명을 누를 때도 변경되는 컴포넌트만 re-render가 되어야 할 것이다. 해당 함수들을 useCallback으로 감쌀 때 두 번째 파라미터인 deps에 있는 state가 변경되면, 값 변경을 감지하고 있던 함수가 호출되고 함수들을 props로 받고 있는 자식 컴포넌트가 re-render가 일어난다. 최적화를 위해 deps를 추가했는데 deps가 최적화를 방해하고 있는 상황이다. 이를 해결하기 위해서는 deps에서 값을 빼야 한다. deps가 없으면 함수 내부에서 최신의 state 값을 조회할 수 없어 문제가 된다. 이때는 set 함수에서 함수형 업데이트를 사용해야 한다.
변경 전: deps에서 users를 감지 변경 후: deps에서 감지하지 않고 함수형 업데이트를 통해 최근 users 값을 사용 한 문단 정리
React.memo를 이용해서 컴포넌트를 내보내면 값 변경이 일어나지 않은 컴포넌트는 re-render 되지 않는다. 그래서 이메일과 계정명을 입력할 때 계정 목록의 re-render을 막을 수 있다. 등록/삭제/업데이트 등의 기능에서도 값이 변경되지 않은 계정 컴포넌트는 re-render가 필요없다. onToggle, onRemove, onCreate 등의 함수의 deps에 users 등의 state가 들어가 있다. users를 감지하고 있으므로 하나의 자식 컴포넌트만 변경돼도, 이 함수들을 props로 가지고 있는 다른 자식 컴포넌트가 전부 re-render된다. 변경되지 않은 컴포넌트의 함수 재사용을 위해서는 함수가 새로 생성되지 않아야 하므로 useCallback을 사용하는 것이고, deps에서 감지하지 못하도록 users를 빼고 나면, state를 설정하는 set 함수에서 함수형 업데이트를 통해 state를 갱신한다. 함수형 업데이트 덕분에 deps에서 감지하고 있지 않아도 최신의 state의 값을 조회할 수 있어 정상적으로 작동한다.
출처: 패스트캠퍼스 벨로퍼트의 리액트 강의
'개발 > React' 카테고리의 다른 글
[Redux] 아주 아주 간단한 리덕스 기본 개념 2 (0) 2022.07.08 [Redux] 아주 아주 간단한 리덕스 기본 개념 (0) 2022.07.08 React & Immer (0) 2022.06.08 [Hooks] useMemo (0) 2021.02.25 [State] 되지만 안 되는 동작 (0) 2021.02.22