프론트 상태관리 도구라고 하면 Context API, Redux, Zustand 등 여러 가지가 있다.
사실 이번 Groupie 사이드 프로젝트 전까지만 해도 난 상태관리 도구 없이 useState만 쓰던 초짜였다.
특강에서 면접 때 상태관리 도구 왜 썼는지 물어보니까 공부해두라는 얘기를 들었다.
찾아보니 최근앤 Zustand가 가볍고 쓰기도 편해서 자주 쓰이는 것 같았다. (내피셜)
프로젝트를 진행하면서 처음에느 로그인/회원가입 모달 상태에 zustand를 도입했고,
최근에는 스터디 필터링 가능에 zustand를 적용했다.
적용하면서 "아 이때 전역 상태관리를 써야 하구나"하고 감이 잡혔다.
useState나 useReducer면 충분처음에는 Context API를 쓸까 했지만,
page.tsx에 필터 버튼만 있는 게 아니라 인기글 컴포넌트, 스터디 리스트도 함께 있어서 <Context.Provider>로 감싸는 구조가 애매했다.
결국 단순 상태 공유와 빠른 반응성을 위해 zustand를 선택했다.
npm install zustand
store폴더를 만들어 그 안에 스토어 파일을 관리한다. 파일명은 xxxStore.ts처럼 작성하는 경우가 많다. // store/modalStore.ts
import { create } from "zustand";
type ModalType = "login" | "signup" | null;
// zustand로 전역 모달 스토어 만들기
interface ModalStore {
openModal: ModalType;
open: (type: ModalType) => void;
close: () => void;
}
export const useModalStore = create<ModalStore>((set) => ({
openModal: null,
open: (type) => set({ openModal: type }),
close: () => set({ openModal: null }),
}));
여기서
interface는 스토어의 상태와 메서드 구조를 정의하는 역할
create()함수는 zustand의 핵심 함수로, 스토어를 실제로 생성한다.
useModalStore()훅을 호출하면 된다.// 예: 로그인 폼에서 모달 닫기
import { useModalStore } from "@/store/modalStore";
export default function LoginForm() {
const { close } = useModalStore();
return (
<button onClick={close}>
닫기
</button>
);
}
이렇게 하면 모달을 여는 컴포넌트, 닫는 컴포넌트가 다른 위치에 있어도 상태를 공유할 수 있다!
기술 스택에 zustand가 있다면 모든 상태를 zustand로 써야 하나?
굳이?
useState가 더 직관적이고 성능도 좋음.예전 발주 페이지에서도 zustand로 전체 상태를 묶었다가,
셀렉트 버튼 상태는 useState로 되돌린 적이 있다.
지금 생각하면, 거기서는 zustand를 쓰지 않아도 됐던 것 같다.
상태 공유가 진짜 필요한가? 를 먼저 고민하는 게 중요하다는 걸 이번에 체감할 수 있었다.
여러 컴포넌트가 공유해야 하거나, 비동기/복잡한 상태일 때 zustand!
그 외엔 useState