의도: 다양한 상태 관리 라이브러리에 대한 지식과 경험 소개 및 해당 라이브러리를 선택하게 된 구체적인 이유를 설명할 수 있는지 확인하는 질문
나의 답안
네, 저는 Zustand를 사용해 본 경험이 있습니다.
Zustand는 Redux보다 훨씬 간결한 문법과 가벼운 구조를 가지고 있어서,
복잡한 보일러플레이트 없이 전역 상태를 빠르게 구성할 수 있다는 장점이 있습니다.
특히 Flux 패턴을 강제하지 않고, 훅 기반으로 간단하게 상태를 읽고 수정할 수 있기 때문에, 소규모 프로젝트나 React Query와 같이 비동기 상태 관리 도구와 병행할 때 유용했습니다.실제 프로젝트에서는 Zustand를 전역 UI 상태(예: 모달, 로그인 상태 등)에 사용하고, React Query를 서버 상태 관리용으로 함께 사용해 클라이언트와 서버 상태를 명확히 분리했습니다.
주어진 답안 (모범 답안)
네, 저는 Redux 외에 zustand라는 전역 상태 관리 라이브러리를 사용한 경험이 있습니다.
기존 Redux와는 다르게 zustand는 보일러 플레이트가 단순하여 더욱 빠른 환경 설정이 가능하다는 장점이 있습니다.
예를 들어 Redux에서 작성해야 했던 액션, 리듀서, 디스패치, 미들웨어 등 대신에, zustand에서는create()메서드를 통해 atomic한 객체를 생성하는 것으로 앞선 과정을 단축할 수 있습니다.또한 Redux에서 채택했던 Flux 아키텍처를 그대로 가져와 사용하였기에 이 또한 저에게 아주 큰 매력으로 다가왔습니다.
왜냐하면 Redux ToolKit을 포함해 Redux를 사용할 때의 가장 큰 장점으로 체감할 수 있었던 것은 바로 개발자 도구(devtool)의 유용함 덕분이었습니다.
zustand는 Redux의 Flux 아키텍처를 그대로 채택하였기에 기존 Redux의 개발자 도구를 이어서 사용할 수 있게 되었고, 이는 곧 저에게 있어서 더 이상 Redux를 사용해야 할 이유를 모두 잃은 것과 다름없었습니다.
React에서 전역 상태 관리는 애플리케이션의 여러 컴포넌트 간에 데이터를 공유하고 효율적으로 업데이트하기 위해 필요한 개념이다.
React는 기본적으로 단방향 데이터 흐름을 따르며, props를 통해 부모에서 자식으로 데이터를 전달한다.
그러나 이러한 방식은 상태가 여러 컴포넌트에서 필요할 때 비효율적일 수 있다.
이를 해결하기 위해 전역 상태 관리 라이브러리를 사용한다.
Redux는 가장 널리 사용되는 상태 관리 라이브러리 중 하나로, 상태를 중앙 저장소(store)에 보관하고 이를 컴포넌트에서 구독(subscribe)할 수 있도록 설게되었다.
type과 추가 데이터를 포함한다.redux-thunk, redux-saga)사용 방법
설치
npm install @reduxjs/toolkit react-redux
설정
1) 스토어 생성: Redux Toolkit의 configureStore를 사용하여 스토어를 설정한다.
// store.ts
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
export const store = configureStore({
reducer: {
counter: counterReducer,
}
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
2) 리듀서 정의
// counterSlice.ts
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { value: 0 },
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
3) React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "./counterSlice";
import { RootState } from "./store";
export default function Counter() {
const count = useSelector((state: RootState) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
}
Zustand는 간단하면서도 강력한 상태 관리 라이브러리로, Redux의 대안으로 떠오르고 있다.
훨씬 간결한 API를 제공한다.
사용 방법
설치
npm install zustand
설정 및 사용
// store.ts
import create from "zustand";
interface CounterState {
count: number;
increment: () => void;
decrement: () => void;
}
const useStore = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
export default useStore;
React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import useStore from "./store";
export default function Counter() {
const { count, increment, decrement } = useStore();
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
React에 내장된 상태 관리 도구로, 컴포넌트 트리 전체에서 데이터를 공유할 수 있도록 한다.
사용 방법
설정 및 사용
// CounterContext.tsx
import React, { createContext, useContext, useState } from "react";
const CounterContext = createContext<any>(null);
export function CounterProvider({ children }: { children: React.ReactNode }) {
const [count, setCount] = useState(0);
return (
<CounterContext.Provider value={{ count, setCount }}>
{children}
</CounterContext.Provider>
);
}
export function useCounter() {
return useContext(CounterContext);
}
React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import { useCounter } from "./CounterContext";
export default function Counter() {
const { count, setCount } = useCounter();
return (
<div>
<button onClick={() => setCount(count - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
// App.tsx
import React from "react";
import { CounterProvider } from "./CounterContext";
import Counter from "./Counter";
export default function App() {
return (
<CounterProvider>
<Counter />
</CounterProvider>
);
}
Recoil은 Facebook에서 만든 라이브러리로, React의 상태 관리 경험을 개선하는 데 중점을 둔다.
사용 방법
설치
npm install recoil
설정 및 사용
// recoil/atoms.ts
import { atom } from "recoil";
export const counterState = atom({
key: "counterState",
default: 0,
});
React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import { useRecoilState } from "recoil";
import { counterState } from "./recoil/atoms";
export default function Counter() {
const [count, setCount] = useRecoilState(counterState);
return (
<div>
<button onClick={() => setCount(count - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
MobX는 상태를 관찰하고 자동으로 업데이트하는 데 초점을 맞춘 라이브러리이다.
사용 방법
설치
npm install mobx mobx-react-lite
설정 및 사용
// store.ts
import { makeAutoObservable } from "mobx";
class CounterStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.count += 1;
}
decrement() {
this.count -= 1;
}
}
export const counterStore = new CounterStore();
React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import { observer } from "mobx-react-lite";
import { counterStore } from "./store";
const Counter = observer(() => {
return (
<div>
<button onClick={() => counterStore.decrement()}>-</button>
<span>{counterStore.count}</span>
<button onClick={() => counterStore.increment()}>+</button>
</div>
);
});
export default Counter;
Jotai는 최소한의 API와 코드로 전역 상태를 관리할 수 있는 라이브러리이다.
사용 방법
설치
npm install jotai
설정 및 사용
// store.ts
import { atom } from "jotai";
export const counterAtom = atom(0);
React 컴포넌트에서 사용
// Counter.tsx
import React from "react";
import { useAtom } from "jotai";
import { counterAtom } from "./store";
export default function Counter() {
const [count, setCount] = useAtom(counterAtom);
return (
<div>
<button onClick={() => setCount(count - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
상태 관리보다는 서버 상태 관리에 초점이 맞춰진 라이브러리이다.