create(...)์ create(...)()zustand store๋ฅผ ์ ์ํ๋ ์์ ๋ฅผ ๋ณด๋ฉด, create(...)์ฒ๋ผ ๊ดํธ ํ๋๋ง ์ฌ์ฉํ๋ ์ฝ๋๋ ์๊ณ , create(...)()์ ๊ฐ์ด ๊ดํธ ๋ ๊ฐ๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ ์๋ค.
| ๊ตฌ๋ถ | create(...) | create(...)() |
|---|---|---|
| ์๋ฏธ | store ์์ฑ ํจ์๋ฅผ ๋ฐํํจ | store ๊ฐ์ฒด ๊ทธ ์์ฒด๋ฅผ ๋ฐ๋ก ์์ฑํจ |
| ์ฌ์ฉ ์ํฉ | ๋ณดํต ๋ค๋ฅธ ํ์ผ์์ store๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํฉํ ๋ฆฌ ํจ์๋ก ์ฌ์ฉํ ๋ | ๋ณดํต ์ฆ์ ์ฌ์ฉํ store๋ฅผ ๋ง๋ค ๋ |
| ๋ฐํ๊ฐ | store ์์ฑ ํจ์ | store ๊ฐ์ฒด (Hook ํฌํจ) |
| ์ฉ๋ | ๋์ค์ ์ฌ๋ฌ ๊ฐ ์์ฑํ๊ณ ์ถ์ ๋ | ์ ์ญ store ํ๋ ๋ง๋ค ๋ |
| ์ฌ์ฉ ์ | ํฉํ ๋ฆฌ ํจํด, ํ ์คํธ์ฉ store | ์ค์ ์ฑ ์ํ ๊ด๋ฆฌ |
create(...)์ create(...)()๋ ๋ณด๊ธฐ์ ๊ดํธ ํ๋ ์ฐจ์ด์ง๋ง, ํ์
์ฒ๋ฆฌ ๋ฐฉ์, ์ฌ์ฉ ๋ชฉ์ , ํ์ฅ์ฑ ๋ฉด์์ ์ค์ํ ์ฐจ์ด๊ฐ ์๋ค.
์ด์ ๋ถํฐ create(...)์ create(...)() ์ฐจ์ด์ ์ ๋ํด ์์ธํ ์์๋ณด์.
create(...) : "ํจ์"๋ฅผ ๋ฐํํ๋ ํํconst makeUserStore = () => {
return create((set) => ({
data: null,
setData: (data: any) => set({ data }),
}));
};
์ด ๊ฒฝ์ฐ create(...)๋ store๋ฅผ ์์ฑํด์ฃผ๋ ํจ์๋ฅผ ๋ฐํํจ
makeUserStore()๋ฅผ ํธ์ถํด์ผ ์ง์ง store๊ฐ ๋ง๋ค์ด์ง
์ฆ, ์ด ๊ตฌ์กฐ๋ store๋ฅผ ๋์ค์ ์ํ๋ ์์ ์ ๋ง๋ค๊ณ ์ถ์ ๋ ์ ์ฉํจ
const userStore = makeUserStore(); // ์ค์ store ๊ฐ์ฒด ์์ฑ
// ์ํ ์ฝ๊ธฐ
const currentData = userStore.getState().data;
console.log("ํ์ฌ ๋ฐ์ดํฐ:", currentData);
// ์ํ ๋ณ๊ฒฝ
userStore.getState().setData("Hello Zustand!");
์ ์ด๋ ๊ฒ ์ฐ๋?
์ฌ๋ฌ store ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๊ฒฝ์ฐ (์: ์ฌ์ฉ์๋ณ store)
// factory.ts
import { create } from "zustand";
export const makeUserStore = (initialName: string) => create(() => ({
name: initialName,
setName: (newName: string) => set({ name: newName }),
}));
// example.ts
const userStore1 = makeUserStore("Alice");
const userStore2 = makeUserStore("Bob");
console.log(userStore1.getState().name); // Alice
console.log(userStore2.getState().name); // Bob
useUserStore Hook์ ์ฌ๋ฌ ์ฌ์ฉ์์ ๋ํด ๋
๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ถ์ ๋userStore1, userStore2๋ ์๋ก ์ํ๋ฅผ ๊ณต์ ํ์ง ์์ โ ๋ฉํฐ ์ธ์คํด์ค ๊ด๋ฆฌ ๊ฐ๋ฅ์ ๋ ํ ์คํธ์์ isolated store๋ฅผ ๋ง๋ค ๋
// counterStore.ts
import { create } from "zustand";
export const makeCounterStore = () => create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
// counterStore.test.ts
import { makeCounterStore } from "./counterStore";
test("increment increases count", () => {
const store = makeCounterStore();
expect(store.getState().count).toBe(0);
store.getState().increment();
expect(store.getState().count).toBe(1);
});
create()๋ฅผ ํจ์๋ก ๊ฐ์ธ์ store๋ฅผ ๋งค๋ฒ ์๋ก ๋ง๋ค ์ ์์ โ ํ
์คํธ์ ์์์ฑ ์ ์งDI(Dependency Injection) ํจํด์ฒ๋ผ store๋ฅผ ์ฃผ์ ํ ํ์๊ฐ ์์ ๋
// storeFactory.ts
import { create } from "zustand";
type TodoStore = {
todos: string[];
addTodo: (todo: string) => void;
};
// ๋
๋ฆฝ๋ store ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ฃผ๋ ํฉํ ๋ฆฌ ํจ์
export const makeTodoStore = (initialTodos: string[] = []) => create<TodoStore>((set) => ({
todos: initialTodos,
addTodo: (todo) => set((state) => ({ todos: [...state.todos, todo] })),
}));
โ๏ธ
storeFactory.ts์ค๋ช
makeTodoStore(): zustand์create(...)๋ฅผ ๋ฐํํ๋ ํจ์- ํธ์ถํ ๋๋ง๋ค ์๋ก์ด store๊ฐ ์์ฑ๋๋ฏ๋ก, ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๋ง๋ค ์ ์์
initialTodos๋ ์ด๊ธฐ๊ฐ์ ์ธ๋ถ์์ ์ ๋ฌ๋ฐ์ โ ์ด๊ธฐ ์ํ ์ ์ฐํ๊ฒ ์ค์ ๊ฐ๋ฅ
// TodoComponent.tsx
import { FC } from "react";
import { makeTodoStore } from "./storeFactory";
interface Props {
store: ReturnType<typeof makeTodoStore>; // store ํ์
์ง์
}
const TodoCompoent: FC<Props> = ({ store }) => {
const todos = store((state) => state.todos); // ์ํ ๊ตฌ๋
const addTodo = store((state) => state.addTodo); // ์ก์
๊ตฌ๋
return (
<div>
<button onClick={() => addTodo("New Task")}>Add</button>
<ul>{todos.map((todo, idx) => <li key={idx}>{todo}</li>)}</ul>
</div>
);
};
โ๏ธ
TodoComponent.tsx์ค๋ช
store๋ props๋ก ์ ๋ฌ๋ฐ์ zustand store ์ธ์คํด์คstore((state) => state.todos): ์ํ๋ฅผ ๊ตฌ๋ ํจ. ์ํ๊ฐ ๋ฐ๋๋ฉด ์๋์ผ๋ก ๋ฆฌ๋ ๋๋ง๋จstore((state) => sttad.addTodo): ์ก์ ๋ ์ด๋ ๊ฒ ์ ๊ทผ ๊ฐ๋ฅaddTodo("New Task")๋ฅผ ๋๋ฅด๋ฉด ์ํ๊ฐ ์ ๋ฐ์ดํธ๋จ โtodos๋ฆฌ์คํธ๋ ์๋ ์ ๋ฐ์ดํธ๋จ- ์ด ๊ตฌ์กฐ๋ React Hook์ธ
useUserStore((state) => state.xxx)์ ์ ํํ ๊ฐ์ ๋์์ ํ์ง๋ง, ์ ์ญ store๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ธ๋ถ์์ ์ฃผ์ ํ๋ค๋ ์ ์ด ๋ค๋ฆ
// App.tsx
const todoStore = makeTodoStore(["Read book"]);
<TodoComponent store={todoStore} />;
โ๏ธ
App.tsx์ค๋ช
todoStore๋ ํ๋์ zustand store ์ธ์คํด์ค["Read book"]์ด๋ผ๋ ์ด๊ธฐ๊ฐ์ผ๋ก ์์ฑ- ์ด store๋ฅผ
TodoComponent์ props๋ก ๋๊ฒจ์ค- ์ด์
TodoComponent๋ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ์ ์ด store๋ง์ ์ฌ์ฉํ๊ฒ ๋จ
store๋ฅผ ์ธ๋ถ์์ ์ฃผ์
(DI: Dependency Injection) โ ์ปดํฌ๋ํธ๊ฐ ์ด๋ค store๋ฅผ ์ธ์ง ์ ์ฐํ๊ฒ ๊ฒฐ์ ๊ฐ๋ฅcreate(...)() : ๋ฐ๋ก ์คํํด์ "store ๊ฐ์ฒด"๋ฅผ ๋ฐํํ๋ ํํ// ์ ์ญ store (store๊ฐ ์ฆ์ ๋ง๋ค์ด์ง)
const useUserStore = create((set) => ({
data: null,
setData: (data: any) => set({ data }),
}));
create()์ ๋ฐ๋ก ํจ์ ๋ฃ๊ณ ๊ทธ ์๋ฆฌ์์ ์คํํด์ ๋ฐ๋ก store ๊ฐ์ฒด๋ฅผ ๋ง๋ฆuseUserStore๋ hook์ฒ๋ผ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ store ๊ฐ์ฒด์const data = useUserStore((state) => state.data);useUserStore๋ useStore Hook์ฒ๋ผ ๋์ํจcreate(...)์ ๋ฆฌํด๊ฐ์ userStore Hook + store ๋ฉ์๋๋ฅผ ๋ด์ ๊ฐ์ฒดcreate ์์ฒด๋ ํจ์์ด๋ฉฐ, ์คํ๋์ด์ผ ์ง์ง store๊ฐ ์๊นcreate(...)()๋ create(...)๋ก ์ค์ ๋ง ๋ง๋ ํ ()๋ก ์ฆ์ ์คํํ๋ ํํcreate()๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ (ํจ์ ๋ฐํ)
const makeStore = () => create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
const store1 = makeStore(); // ๊ฐ๊ฐ ๋ค๋ฅธ store
const store2 = makeStore();
store1, store2๋ ๊ฐ๊ฐ ๋
๋ฆฝ๋ ์ํ ๊ฐ์งcreate()()๋ก ๋ฐ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ (๊ณต์ฉ store)
const userCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
useCounterStore๋ ์ฑ ์ ์ฒด์์ ๋์ผํ store ์ธ์คํด์ค๋ฅผ ๊ณต์ ํจ