반응형
Intro
최상단에 Home 컴포넌트가 있고, 하위로 다양한 컴포넌트가 있는 구조가 있다고 하자.
그럼 하위 컴포넌트에서 상태값이 바뀔 때마다 Home 컴포넌트도 리렌더링된다.
Home
|-- Memo
|-- Summary
|-- Dialog
ㄴ-- ...
이를 방지하고자 zustand에서는, shallow를 제공한다.
shallow
기본적으로 zustand는 엄격한 비교(old === new)로 변경사항을 감지한다.
그래서 state가 변경될 때마다 컴포넌트가 리렌더링된다.
const nuts = useBearStore((state) => state.nuts)
const honey = useBearStore((state) => state.honey)
만약 state가 하나의 객체에서 일부 state들을 한꺼번에 가져오고 싶을 때, zustand에게 shallow를 전달하여 얕은 비교를 하고 싶다고 알릴 수 있다.
그러면 모든 state가 바뀔 때마다가 아니라, 일부 선택한 state만 바뀔 때마다 리렌더링된다.
import { shallow } from 'zustand/shallow'
// Object pick, re-renders the component when either state.nuts or state.honey change
const { nuts, honey } = useBearStore(
(state) => ({ nuts: state.nuts, honey: state.honey }),
shallow
)
// Array pick, re-renders the component when either state.nuts or state.honey change
const [nuts, honey] = useBearStore(
(state) => [state.nuts, state.honey],
shallow
)
// Mapped picks, re-renders the component when state.treats changes in order, count or keys
const treats = useBearStore((state) => Object.keys(state.treats), shallow)
shallow.d.ts
export default function shallow<T, U>(objA: T, objB: U): boolean;
A, B를 비교하고, 바뀌었을 때 true를 반환해줌
import shallow from 'zustand/shallow';
const [action1, action2, action3] = store(state => [state.action1, state.action2, state.action3]);
shallow를 사용하면 action1, action2, action3이 바뀔 때에만 리렌더링이 된다.
하위 컴포넌트들에도 모두 shallow를 적용해주면 컴포넌트가 최적화된다.
zustand에서도 shallow를 사용하는 것을 권장한다.
여기서 더 나아가서 리렌더링을 제어하고 싶으면, custom equality function(compare)을 주자.
const treats = useBearStore(
(state) => state.treats,
(oldTreats, newTreats) => compare(oldTreats, newTreats)
)
참고 자료
GitHub - pmndrs/zustand: 🐻 Bear necessities for state management in React
반응형
'Front-End: Web' 카테고리의 다른 글
[CSS] Background 속성 작성 순서: The Order of the Background Shorthand Property (0) | 2024.01.29 |
---|---|
zustand: subscribeWithSelector로 subscribe하기 (0) | 2023.07.30 |
[React-Query] createJSONStorage (0) | 2023.07.30 |
React Query: Optimistic Updates (0) | 2023.07.22 |
절대 경로 설정하기 (craco + typescript + storybook) (0) | 2023.07.22 |