useShallow
포스트
취소

useShallow

useShallow

정의

  • selector의 반환 값을 얕은 비교로 판단하여 불필요한 리렌더링을 방지하는 훅
  • Zustand에서 제공하는 훅
  • 객체의 속성 값들이 변경되었을 때만 컴포넌트를 리렌더링한다.
  • Object.is와 유사하게 동작한다.

특징

  • 얕은 비교
    • 객체의 참조가 아닌, 내부 속성 값들을 얕게 비교하여 변경 여부를 판단한다.
  • 랜더링 최적화
    • useStore(selector)를 사용할 때, selector가 반환하는 객체가 동일한 참조를 유지하더라도
      내부 값이 변경되면 리렌더링을 유발할 수 있다.
    • useShallow를 사용하면 위의 경우에 발생하는 리랜더링을 방지할 수 있다.
  • 선택적 구독
    • 컴포넌트가 필요한 상태만 선택적으로 구독할 수 있다.

장점

  • 불필요한 리렌더링을 줄여 애플리케이션의 성능을 향상시킬 수 있다.
  • 동일한 객체 상태의 일부를 구독하는 컴포넌트의 수가 많을수록 효과적이다.
  • 객체나 배열 등에서 최상위 값만 변경될 때 리랜더링된다.
  • selector 패턴과 결합하기 쉽다.

단점

  • 깊은 비교가 필요할 때는 사용할 수 없다.
    • 내부 객체나 배열의 변경은 감지하지 못 한다.
  • 남용하면 오히려 문제가 커질 수 있다.
    • 가독성을 해칠 수도 있다.
    • 리랜더링이 필요한데 리랜더링이 안 될 수도 있다.

기본 사용법

import하기

useState 사용하듯이 import 받아서 사용하면 된다.

import { useShallow } from 'zustand/react/shallow';

저장소 코드

import { create } from "zustand";

const useUserStore = create(
  (set, get) => ({
    userInfo: {
      name: '',
      email: '',
    },
    updateName: (newName) =>
      set({
        userInfo: { ...get().userInfo, name: newName },
      }),
    updateEmail: (newEmail) =>
      set({
        userInfo: { ...get().userInfo, email: newEmail },
      }),
  }
));

export default useUserStore;

실제 사용법

import useUserStore from "../../store/03_useShallow/useUserStore";
import { useShallow } from 'zustand/shallow';

function Component() {
  // userInfo 객체의 name, email 중 하나라도 변경되면 리렌더링
   const {  name, email, updateName, updateEmail }  = useUserStore(
    useShallow(
      (state) => ({
        name: state.userInfo.name,
        email: state.userInfo.email,
        updateName: state.updateName,
        updateEmail: state.updateEmail,
      }),
    )
  ); 
  console.log("랜더링 실행");

  return (
    <div>
      <h2>회원 정보</h2>
      <p>Name: {name}</p>
      <p>Email: {email}</p>
      <button onClick={() => updateName('누군가의 이름')}>이름 수정</button>
      <button onClick={() => updateEmail('누군가의 이메일')}>이메일 수정</button>
    </div>
  );
}

export default Component;
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.