[React] useSelector의 타겟팅에 따른 리렌더링 로직

yongkini ·2022년 10월 12일
0

React

목록 보기
6/19

useSelector의 타겟팅에 따른 리렌더링 로직

목표

: 하나의 redux state 단위(객체라고 했을 때)에서 하위 depth의 프로퍼티 값을 변경했을 때(dispatching),
useSelector 가 뭐를 타겟으로 하고 있냐에 따라 리렌더링 로직이 어떻게 바뀌는지를 확인하고자 합니다.
예를 들어, server 라는 redux state 에

{
  members: { host: [], guest: [] },
  spaces: { spaceNames: [], spaceNumbers: [] },
}

이런식으로 데이터가 있다고 가정했을 때,

const initialState: ServerState = {
  members: { host: [], guest: [] },
  spaces: { spaceNames: [], spaceNumbers: [] },
};

위와 같은 상황을 가정했을 때, members에 hosts에 push를 하면(dispatch)
spaces를 구독하고 있는 컴포넌트 혹은 server state 자체를 구독하고 있는 컴포넌트 등에서 리렌더링이 일어나는지 안나는지 등을 확인하고자 합니다.

구현을 통한 테스트

App.tsx (최상위 컴포넌트)
Spaces.tsx & Members.tsx(하위 컴포넌트 & 같은 레이어) 와 같은 구조로 돼있다고 했을 때,

Spaces에서는

  const spacesNames = useSelector(
    (state: RootState) => state?.server.spaces.spaceNames
  );

Members 에서는

  const hostMembers = useSelector(
    (state: RootState) => state?.server.members.host
  );

각각을 구독하고 있습니다. 마지막으로 App에서는

  const server = useSelector((state: RootState) => state?.server);

를 구독하고 있습니다.


:: 리렌더링이 되면 테두리가 표시되도록 했습니다.

결과

위의 상황에서 server state와 같이 최상위 depth인 state를 구독하는 A라는 컴포넌트가 있을 때, 하위 depth state(예를 들어, members 등)를 B 컴포넌트에서 업데이트 하면 무조건 A 컴포넌트는 리렌더링 됩니다. 이 때 React.memo 등을 써서 막아놓지 않으면 A 컴포넌트의 하위 컴포넌트도 당연히 리렌더링 됩니다.
하지만 역으로 하위 depth의 프로퍼티를 구독하고 있을 때는, 예를 들어, 아래와 같이

  const hostMembers = useSelector(
    (state: RootState) => state?.server.members.host
  );

특정 depth의 프로퍼티를 타겟팅해서 구독하고 있는 컴포넌트 B는 해당 property가 업데이트 되지 않는 이상 리렌더링 되지 않습니다(물론 부모 컴포넌트가 리렌더링되고 React.memo 등의 최적화를 안해놨다면 리렌더링 됩니다). 즉, 다른 컴포넌트에서 server.members.host가 아닌 depth server.members.guest라는 프로퍼티가 있다고 했을 때 host만 건들지 않으면 리렌더링 되지 않습니다(같은 depth라도 구독중인 프로퍼티만 건들지 않으면 됩니다.).

결론

  • 최적화(리렌더링 시간이 오래걸린다 했을 때) 측면에서 상위에 있는 컴포넌트에서 상위 depth의 state를 구독하는건 React.memo 등 최적화 툴을 쓴다해도 낭비라고 볼 수 있습니다. 따라서, 많은 data를 참조해야하는 컴포넌트이면 아예 컴포넌트 자체를 쪼개서 관리하던지(Z컴포넌트를 A,B,C로 나눠서 각각에 state를 나눠서 구독하는 등) 하는 편이 좋겠습니다.
  • 위와는 반대되지만 유사한 말입니다만, 컨벤션으로 state를 useSelector로 받아서 쓸 때는 쓸 state만 정확히 타겟팅해서 구독하는 방식을 채택하는게 좋을 것 같습니다.
  • 추가로 로컬에서 작업을 하실 때 React에서 제공하는 'Profiler’를 사용해서 리렌더링이 얼마나 이용하는지를 체크해보면서 작업하셔도 좋을 것 같습니다.
profile
완벽함 보다는 최선의 결과를 위해 끊임없이 노력하는 개발자

0개의 댓글