이번에 하는 고급 프로젝트에서 상태 관리를 Zustand를 이용해서 하기로 했어서, Zustand가 어떤 넘인지 감을 잡기 위해 간단히 글을 써본다.
Zustand는 React 상태 관리를 위한 경량 라이브러리로, 사용하기 쉽고 빠르며, 최소한의 보일러플레이트로 설계되었다. Redux와 같은 상태 관리 라이브러리에 비해 간단하면서도 강력한 기능을 제공한다! 이제 Zustand의 주요 개념과 사용 방법을 살펴보려한다.
Zustand의 주요 개념
- 스토어(store): Zustand의 핵심은 스토어다. 스토어는 전역 상태를 보관하고 관리한다. 모든 상태와 액션은 스토어를 통해 이루어진다.
- 미들웨어(Middleware): 미들웨어를 통해 상태 변경을 가로채고 추가 로직을 삽입할 수 있다. 예를 들어, 로깅이나 상태 유지(persist) 기능을 미들웨어로 추가할 수 있다.
- React 훅을 통한 사용: Zustand는 React 훅을 사용하여 상태를 관리한다. useStore 훅을 사용하여 스토어의 상태와 액션을 가져올 수 있다.
Zustand 설치
Zustand를 사용하려면 먼저 패키지를 설치해야 한다.
npm install zustand
yarn add zustand 등등...
Zustand 기본 사용법
Zustand를 사용하여 간단한 스토어를 만들어보좌.
- 스토어 생성: 먼저, 상태와 액션을 정의하는 스토어를 생성한다.
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}));
2. 상태 사용: React 컴포넌트에서 Zustand 스토어를 사용하여 상태를 가져오고 액션을 호출할 수 있다.
import React from 'react';
import { useStore } from './store';
function Counter() {
// 상태를 개별적으로 구독
const count = useStore((state) => state.count);
const increase = useStore((state) => state.increase);
const decrease = useStore((state) => state.decrease);
return (
<div>
<h1>{count}</h1>
<button onClick={increase}>Increase</button>
<button onClick={decrease}>Decrease</button>
</div>
);
}
export default Counter;
이때 중요한 건, 상태와 액션을 호출할때 구조분해할당 방식으로
const { count, increase, decrease } = useStore();
처럼 한번에 불러오는 것은 좋지 않다.
왜냐하면 Zustand의 상태와 액션을 한 번에 가져오는 방식은 불필요한 리렌더링을 유발할 수 있고,
이는 React 컴포넌트의 성능에 부정적인 영향을 줄 수 있기 때문이다.
그래서 위 코드처럼 개별적으로 상태와 액션을 구독하는 것이 좋다. 이렇게 하면 필요하지 않은 상태 변경에 대한 리렌더링을 피할 수 있다.
즉, 상태와 액션을 개별적으로 구독하는 이유를 정리하자면,
- 리렌더링 최적화: 개별적으로 상태를 구독하면 특정 상태가 변경될 때만 해당 상태를 사용하는 컴포넌트가 리렌더링된다. 이를 통해 불필요한 리렌더링을 방지할 수 있다.
- 더 나은 성능: 전체 상태 객체를 구독할 때보다 특정 상태나 액션만 구독함으로써 성능을 향상시킬 수 있다. 이는 특히 상태 객체가 클 때 유용하다.
Zustand의 고급 사용법
- 미들웨어 사용: 미들웨어를 통해 추가 기능을 구현할 수 있다.
예를 들어, 상태를 로컬 스토리지에 저장하려면 zustand/middleware의 persist를 사용할 수 있다.
import create from 'zustand';
import { persist } from 'zustand/middleware';
const useStore = create(
persist(
(set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}),
{ name: 'counter-storage' }
)
);
2. 비동기 작업: 비동기 작업을 상태 액션에 포함할 수 있다. 예를 들어, API 호출을 상태 변경과 함께 수행할 수 있다.
import create from 'zustand';
const useStore = create((set) => ({
data: null,
loading: false,
error: null,
fetchData: async (url) => {
set({ loading: true });
try {
const response = await fetch(url);
const data = await response.json();
set({ data, loading: false });
} catch (error) {
set({ error, loading: false });
}
},
}));
3. 파생 상태(Derived State): 상태에서 파생된 값을 계산할 수 있다.
import create from 'zustand';
const useStore = create((set) => ({
items: [],
addItem: (item) => set((state) => ({ items: [...state.items, item] })),
itemCount: (state) => state.items.length,
}));
결론
Zustand는 간결하고 강력한 상태 관리 라이브러리로, React 애플리케이션에서의 상태 관리를 단순하게 만들어준다. 적은 설정과 사용하기 쉬운 API를 통해 개발자는 보다 직관적으로 상태를 관리할 수 있는 게 느껴진다.
여튼 Zustand를 사용하면 전역 상태 관리가 훨씬 쉬워지며, 미들웨어와 비동기 작업도 간편하게 통합할 수 있으니 관심있다면 한번 츄라이츄라이~~ 해보는 것도 좋을 것 같다.
'개발냥발 > FE (FrontEnd)👩🏻💻' 카테고리의 다른 글
2024 프론트엔드 기술 스택 트렌드 이모저모 _아티클 요약 (0) | 2024.07.15 |
---|---|
Next.js...그리고 react query와 prefetch, hydration까지 (0) | 2024.06.05 |
React Query의 suspense와 error boundary 활용하기 (feat. Next.js의 App router) (0) | 2024.05.21 |
Redux 익히기❗ (0) | 2022.06.20 |
Typescript 익히기❗ (0) | 2022.06.13 |