적용 배경
- 현재 진행 중인 프로젝트가 점점 디벨롭을 거듭하며 컴포넌트의 갯수가 많아지고, Depth가 깊어지며 Props Drilling 현상이 생기기 시작했다.
- 기존엔 최상위 컴포넌트에서 로그인 및 다크모드 상태를 관리했는데, 다크모드 상태를 필요로 하는 몇몇 컴포넌트가 최상위 컴포넌트와의 Depth 차이가 많이 났을 뿐더러, 추후를 위해서라도 상태 관리 라이브러리를 도입하는 것이 좋을 것이라 생각하였다.
- 보일러 플레이트가 크지 않고, 무엇보다 상태 관리에 많은 시간을 쏟지 않고 메인 로직에 집중하고 싶었다.
- 그 중 zustand를 살펴보게 되었고, 사용이 간편하며 상태 저장 및 관리하는 구조도 마음에 들었고, Provider 작성이 불필요하며 비효율적인 리렌더링을 최소화할 수 있어, 추후 성능 최적화하는 데도 이점이 될 것 같아 채택하게 되었다.
기본 사용 예시
- 공식 문서에 의하면 아래와 같이 사용 가능하다.
import { create } from 'zustand'
const useStore = create((set) => ({
count: 1,
inc: () => set((state) => ({ count: state.count + 1 })),
}))
function Counter() {
const { count, inc } = useStore()
return (
<div>
<span>{count}</span>
<button onClick={inc}>one up</button>
</div>
)
}
- 보다시피 매우 단순하다. 이전에 재직하던 회사에서 Redux를 사용했었는데 상태 관리하는 코드가 정말 방대해서 파악하는데만 많은 시간이 소요됐던 기억이 난다.. 이렇게 간편하게 상태 관리를 할 수 있다는 데에 오픈소스 개발자들에게 감사하다는 생각이 들었다.
적용
- 나는 로그인, 다크모드 상태를 아래와 같이 전역 상태 관리하였다.
/** 로그인 전역 상태 및 상태 갱신 함수 */
import { create } from "zustand";
interface AuthState {
isLoggedIn: boolean;
loginSuccess: (token: string) => void;
logOut: () => void;
}
const useAuthStore = create<AuthState>((set) => ({
isLoggedIn: localStorage.getItem("token") ? true : false,
loginSuccess: (token: string) => {
localStorage.setItem("token", token);
set((state) => ({ isLoggedIn: true }));
},
logOut: () => {
localStorage.removeItem("token");
set((state) => ({ isLoggedIn: false }));
},
}));
export default useAuthStore;
/** themeMode 전역 상태 및 상태 갱신 함수 */
import { create } from "zustand";
import theme from "../styles/layout/themes";
import { getInitialTheme } from "../utils/themeUtils";
interface ThemeStore {
themeMode: keyof typeof theme;
changeTheme: () => void;
}
const useThemeStore = create<ThemeStore>((set, get) => ({
themeMode: getInitialTheme(),
changeTheme: () => {
const newTheme = get().themeMode === "light" ? "dark" : "light";
localStorage.setItem("themeMode", newTheme);
set({ themeMode: newTheme });
},
}));
export default useThemeStore;
/** 로그인 전역 상태 */
const { isLoggedIn } = useAuthStore();
/** theme 전역 상태 */
const { themeMode, changeTheme } = useThemeStore();
- 외부 컴포넌트에서 위와 같이 import하여 사용하면 끝. 정말 감탄스럽다.
후기
- 다양한 종류의 오픈소스 상태관리 라이브러리들이 존재하지만, 이번에 zustand를 도입 및 사용하며 상태 관리에 많은 시간을 쏟지 않으니 메인 로직에 더욱 집중할 수 있었다.
- 추후 zustand의 동작 원리 및 특징에 대한 자세한 글을 작성하려 한다.