• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    해결됨

useSelector 과 컴포넌트 렌더링

20.09.20 14:32 작성 조회수 349

1

5:00 즘에 shallowEqual 은 value3 이 가지고 있는 모든 속성값을 다 비교해서 비효율 적인 측면이 있다고 하셨는데요. 이 부분 좀 더 설명해 주실 수 있을까요? 

function useMySelector(selector) {
    return useSelector(selector, shallowEqual)
}

// value3 의 모든 속성값을 비교하기 때문에 비효율
const value3 = useMySelector(state => state.value3);

// 이렇게 해주는게 좋다고 함. 이유는 잘 모르겠음.
const [value3] = useMySelector(state => [state.value3]);

위에 value3 를 꺼내오는 방법 2가지를 작성해 두었는데 후자의 방법이 좋다고 하셨는데 왜 배열로 하면 더 좋은지를 모르겠습니다. 그리고

function useMySelector(selector) {
    return useSelector(selector, shallowEqual)
}

// shallowEqual O, 배열 X
const value3 = useMySelector(state => state.value3);
// shallowEqual O, 배열 O
const [value3] = useMySelector(state => [state.value3]);
// shallowEqual 옵션 x, 배열 X
const value3 = useSelector(state => state.value3); 

value3 를 불러오는 위 3가지 케이스의 차이를 알 수 있을까요? 

아마 제가 얕은 비교라는 말에 대해서 뭔가 잘 못 알고 있어서 더 헷갈리는 것 같은데 얕은 비교에 대한 정의도 한번 해주시면 좋을 것 같습니다.

답변 3

·

답변을 작성해보세요.

1

정확합니다!

1

슈퍼장님의 프로필

슈퍼장

질문자

2020.09.22

아래는 제가 이해한 내용인데 혹시 잘 못 이해한 부분이 있으면 짚어주시면 감사하겠습니다. 

예제에서 shallowEqual 를 사용하지 않은 useSelector(state => state.value3) 는 이미 레퍼런스 비교를 하기 때문에 굳이 shallowEqual 를 사용할 필요가 없음. (오히려 shallowEqual 사용시 1-depth 객체의 모든 속성을 비교하기 때문에 비효율)

useMySelector(state => [state.value3]) 처럼 [] 형식으로 store 의 값을 꺼낼 경우 액션이 dispatch 될 때마다 매번 배열이 생성되고, 때문에 실제로 상태 변경이 없더라도 매번 컴포넌트가 렌더링 될 수 있는데, shallowEqual 사용해서 [] 의 1-depth 배열 아이템을 비교하도록 강제해서 변경 유무를 캐치하여 불필요한 렌더링을 하지 않도록함.

답변 감사합니다! 

1

얕은 비교는 1-depth 깊이에 있는 속성만 비교합니다.
따라서 2-depth 이상 깊이 있는 속성의 값은 비교하지 않습니다.
얕은 비교에서 'state => [state.value3]' 이렇게 입력하면 배열의 아이템만 비교하는거라서 'prevItems[0] === nextItems[0]' 처럼 한 번의 비교로 끝납니다.
만약 'state => state.value3' 이렇게 입력했다면 value3에 1-depth로 붙어있는 모든 속성을 비교합니다. (속성이 100개면 100번 비교)
사실 value3을 불변 객체로 관리했다면 한 번의 비교면 충분한거라서, 여러 번 비교하는건 비효율적이거든요

useSelector 는 직접 비교를 합니다 (1번의 레퍼런스 비교)
따라서 아래 두 코드는 모두 1번의 비교만 하게 됩니다.
useMySelector(state => [state.value3])
useSelector(state => state.value3)
참고 링크: https://react-redux.js.org/api/hooks#equality-comparisons-and-updates

참고로 아래는 얕은 비교 코드입니다
https://github.com/facebook/react/blob/a9b035b0c2b8235405835beca0c4db2cc37f18d0/packages/shared/shallowEqual.js#L19

얕은 비교를 설명하는 '렌더링 속도를 올리기 위한 성능 최적화 방법1' 8:25 부분도 참고해주세요