React 최적화 방법(React.memo, useCallback)

Marco·2022년 1월 24일
1

React

목록 보기
2/8
post-thumbnail

컴포넌트에 대한 불필요한 재평가 방지를 위한 최적화 방법(React.memo())

함수형 컴포넌트를 export할 때, React.memo로 wrapping하여 최적화한다.
React.memo는 인자로 받은 컴포넌트에 어떤 props가 들어가는지 확인한다.
그리고 모든 props 값을 확인하고 그 값을 props가 이전에 받은 값과 비교하여, props 값이 변경된 경우에만 컴포넌트를 재실행 및 재평가한다.
부모 컴포넌트가 바뀌었지만 props는 바뀌지 않은 경우, 해당 자식 컴포넌트는 재실행되지 않는다.
이렇게 최적화를 하여 불필요한 렌더링을 막는다.

export default React.memo(DemoOutput);
  • 그렇다면 모든 컴포넌트를 최적화하면 되지 않을까?

    • 하지만 최적화를 하는 데에는 조건이 있다.
    • 자식 컴포넌트가 많아서 컴포넌트 트리가 크면 React.memo가 유용하다. 컴포넌트 트리의 상위에서 컴포넌트 트리의 불필요한 가지를 재실행하는 걸 방지한다. 대규모 앱은 불필요한 재평가 방지를 위해 컴포넌트 트리 가지를 잘라내는 것이 좋다.
    • 반면, 부모 컴포넌트를 재평가할 때마다 컴포넌트나 컴포넌트의 props가 계속 변하는 경우라면, React.memo는 효율적인 선택이 아니다. 왜냐하면 컴포넌트가 다시 실행될 때마다 props 값을 비교한 데이터가 저장되는데, 비효율적이기 때문이다. 물론 앱 규모에 달렸다. 모든 컴포넌트에 React.memo를 쓰기보다 컴포넌트 트리의 뿌리를 골라서 자식 컴포넌트의 가지를 잘라 내는 것이 자식 컴포넌트를 다 실행하는 것보다 더 효율적이다.
  • props 값에 변하지 않은 함수만 들어있음에도 불구하고 리액트에서 props 값이 변경되었다고 보고 컴포넌트가 재실행 및 재평가되는 이유는 객체인 함수는 매번 실행할때마다 재생성되어 이전과 다르다고 판단되기 때문이다.

useCallback()으로 함수 재생성 방지하기

  • useCallback()을 사용함으로써 객체인 prop 값에 대해서도 React Memo가 작동하도록 만들 수 있다. 객체들을 만들고 저장하는 방식을 useCallback 후크로 조금 수정하면 된다. useCallback은 기본적으로 컴포넌트 실행 전반에 걸친 함수를 저장하는 후크이다. 즉 React에 함수를 저장하여 이 함수를 매 실행마다 재생성하지 말라고 알리는 것이다. 그러면 동일한 함수 객체 중 하나가 메모리 내의 동일한 위치 중 하나에 저장되고, 그렇게 항상 동일한 함수 객체를 재사용할 수 있다.
  • 사용 방법은 저장하고 싶은 함수를 useCallback()의 첫 번째 인수에 넣어주고, 두 번째 인수에는 의존성 배열을 주입하며 함수에서 사용하는 모든 state, props, context를 배열에 넣어준다. 이 상황에서는 해당 함수가 절대 변경되지 않는 것임을 전제하였으므로, 의존성에 빈 배열만 넣어줘도 된다. 그래서 앱 컴포넌트가 리렌더링될 때 동일한 함수 객체가 재사용된다.
const somethingHandler = useCallback(() => {
  setSomething(prevState => !prevState);
}, []);
profile
블로그 이사 🚚 https://wonsss.github.io/

0개의 댓글