Zustand Store โ
๐ก Point
- Zustand๋ ์ํ(state)์ ๋ก์ง(action)์ ํ ๊ณณ์ ๋ชจ์ ๊ด๋ฆฌํ ์ ์๋ ๊ฐ๋ฒผ์ด ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
useAppStore๋ผ๋ ํ ์ ๋ง๋ค์ด๋๋ฉด, ์ปดํฌ๋ํธ ์์์ ๋ฐ๋ก ๋ถ๋ฌ์์ ๊ฐ์ด๋ ํจ์๋ฅผ ์ธ ์ ์๋ค.useAppStore()๋ ํ ์ด๋ฏ๋ก ๋ฌด์กฐ๊ฑด ํจ์์ฒ๋ผ ํธ์ถํด์ผ ํ๋ค.useAppStore((state) => state.count)๊ฐ์ด ์ ํ์๋ฅผ ์ฐ๋ฉด ํ์ํ ๊ฐ๋ง ๊ตฌ๋ ํด์ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ค์ผ ์ ์๋ค.- ํ ๋ฒ ๋ง๋ ์คํ ์ด๋ ์ฑ ์ ์ฒด์์ ๋จ์ผ ์ธ์คํด์ค(์ฑ๊ธํค)๋ก ๋์ํด, ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ์ํ๋ฅผ ๊ณต์ ํ ์ ์๋ค.
1. Store ์์ฑํ๊ธฐ โ
useAppStore๋ ๋จ์ํ ๋ณ์์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ค์ ๋ก๋ React์์ ์คํ ๊ฐ๋ฅํ ์ปค์คํ
ํ
์ด๋ค.
์ปดํฌ๋ํธ ์์์ ํธ์ถํ๋ฉด Zustand๊ฐ ์๋์ผ๋ก ๊ตฌ๋
์ ๊ฑธ๊ณ , ์ํ๊ฐ ๋ฐ๋๋ฉด ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋งํ๋ค.
import { create } from "zustand";
interface StoreState {
count: number; // ์ํ (state)
increment: () => void; // ์ํ๋ฅผ ๋ฐ๊พธ๋ ํจ์ (action)
}
const useAppStore = create<StoreState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
export default useAppStore;create: Zustand์ ํต์ฌ ํจ์, store๋ฅผ ์์ฑํ๋ค.set: Zustand๊ฐ ์ ๊ณตํ๋ ์ํ ์ ๋ฐ์ดํธ ํจ์.count: ์ํ(state) โ ํ์ฌ ๊ฐ ์ ์ฅ์ (์ฌ๊ธฐ์ ๊ธฐ๋ณธ๊ฐ 0)increment: action โset์ ์ด์ฉํด count๋ฅผ 1 ์ฆ๊ฐ์ํค๋ ํจ์
๐งฉ ํ์ ์ค๊ณ TypeScript
ํ์ ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ โ
interface StoreState {
count: number; // ์ซ์ ํ์
increment: () => void; // ์ธ์ ์์, ๋ฐํ๊ฐ ์์
}StoreState๋ผ๋ ์ด๋ฆ์ ํ์ ์ค๊ณ๋ ์์ฑ
count: ๋ฐ๋์ ์ซ์์ฌ์ผ ํ๋ค.increment: ๋ฐ๋์ ํจ์์ฌ์ผ ํ๋ฉฐ, ๋งค๊ฐ๋ณ์์ ๋ฐํ๊ฐ์ด ์๋ค.
์ด๋ ๊ฒ ํ์
์ ์ ์ํ๋ฉด, store.count = "abc" ๊ฐ์ ์ค์๋ฅผ ์ปดํ์ผ ๋จ๊ณ์์ ๋ง์ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ผ๋ฉด? โ
const store = {
count: 0,
increment: function () {
store.count += 1;
},
};JS์์๋ ๊ตฌ์กฐ๋ง ๋ง์ผ๋ฉด ๋ฌธ์ ์์ด ๋์ํ๋ค. ํ์ง๋ง TS๋ ํ์ ๊ท์น์ ์๊ฒฉํ ์ง์ผ์ผ ํ๋ฏ๋ก ์์ ์ฑ์ด ๋์์ง๋ค.
2. ์ปดํฌ๋ํธ์์ store ์ฌ์ฉํ๊ธฐ โ
import useAppStore from "./store/useAppStore";
function App() {
const { count, increment } = useAppStore();
return (
<div>
<h1>Hello Zustand</h1>
<p>{count}</p>
<button onClick={increment}>increment</button>
</div>
);
}
export default App;import useAppStore from "./store/useAppStore";
function App() {
// 1. ๊ฐ๊ฐ ๊บผ๋ด ์ฐ๋ ๋ฐฉ๋ฒ (์ ํ์ ์ฌ์ฉ)
// const count = useAppStore((state) => state.count);
// const increment = useAppStore((state) => state.increment);
// 2. ๊ตฌ์กฐ๋ถํด ํ ๋น์ผ๋ก ํ ๋ฒ์ ๊บผ๋ด๊ธฐ (์คํ ์ด ์ ์ฒด์์ ๊บผ๋)
const { count, increment } = useAppStore();
return (
<div>
<h1>Hello Zustand</h1>
<p>{count}</p>
{/* ํ์ดํ ํจ์๋ก ๊ฐ์ ํ์ ์์ */}
{/* <button onClick={() => increment()}>increment</button> */}
{/* ํจ์ ๋ ํผ๋ฐ์ค๋ฅผ ์ง์ ์ ๋ฌ (increment๊ฐ ํจ์์ด๋ฏ๋ก ๊ทธ๋๋ก ์ ๋ฌ ๊ฐ๋ฅ) */}
<button onClick={increment}>increment</button>
</div>
);
}
export default App;import { create } from "zustand";
interface StoreState {
count: number;
increment: () => void;
}
const useAppStore = create<StoreState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
export default useAppStore;onClick={increment}: ๋ฒํผ์ด ํด๋ฆญ๋๋ฉดincrement์คํonClick={() => increment()}: ๋ฒํผ ํด๋ฆญ ์ ์ต๋ช ํจ์ ์คํ, ๊ทธ ์์์increment()ํธ์ถ
ํ์ฌ ์ฝ๋์์ ๋ ๋ฐฉ์์ด ๋์ผํ์ง๋ง, ๋งค๊ฐ๋ณ์๋ฅผ ๋๊ฒจ์ผ ํ ๋๋ ํ์ดํ ํจ์๊ฐ ํ์ํ๋ค.
์ํ ๊ตฌ๋ ๋ฐฉ์ โ
useAppStore((state) => state.count): count๋ง ๊ตฌ๋useAppStore((state) => state.increment): increment๋ง ๊ตฌ๋useAppStore(): ์คํ ์ด ์ ์ฒด๋ฅผ ๊ฐ์ ธ์ ํ์ํ ๊ฐ ๊บผ๋
ํ์ํ ๊ฐ๋ง ์ ํ์ ์ผ๋ก ๊ตฌ๋ ํ๋ฉด ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ค์ผ ์ ์๋ค.
์คํ ํ๋ฆ ์์ฝ โ
- ์ฑ ์์ โ useAppStore ์์ฑ (count=0, increment ์ค๋น๋จ)
- App ์ปดํฌ๋ํธ๊ฐ count ๊ตฌ๋
- ๋ฒํผ ํด๋ฆญ โ increment ์คํ โ count + 1
- Zustand๊ฐ ๊ฐ ๋ณ๊ฒฝ ๊ฐ์ง โ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง
- ์๋ก์ด count ๊ฐ์ด ํ๋ฉด์ ๋ฐ์
์จ๊ฒจ์ง ์ ํธ โ
Zustand store๋ ํ ์ด๋ฉด์ ๋์์ ์คํ ์ด ํธ๋ค์ ๊ฐ์ง๋ค.
useAppStore.getState() // ํ์ฌ ์ํ ๊ฐ์ ธ์ค๊ธฐ
useAppStore.setState(...) // ์ํ ์ง์ ๋ณ๊ฒฝ
useAppStore.subscribe(...)// ์ํ ๋ณ๊ฒฝ ๊ตฌ๋
์ฆ, React ํ ์ฒ๋ผ ์ฐ๋ฉด์๋, ๋ฆฌ์กํธ ๋ฐ๊นฅ์์๋ ์ํ๋ฅผ ์ ์ดํ ์ ์๋ค.