Skip to content

Commit dddfb5f

Browse files
committed
[zustand] overview, 설명
1 parent da82b8e commit dddfb5f

File tree

7 files changed

+252
-0
lines changed

7 files changed

+252
-0
lines changed

zustand/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

zustand/image-1.png

26.4 KB
Loading

zustand/image-2.png

32.4 KB
Loading

zustand/image.png

26.2 KB
Loading

zustand/overview.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Zustand 5.0.5
2+
3+
- 작고 빠르며 확장 가능한 React 프로젝트에서 사용하는 상태 관리(Store) 라이브러리이다.
4+
5+
## v5
6+
7+
- React v18 이상 필요
8+
- TypeScript v4.5 이상 필요
9+
- UMD/SystemJS 지원 중단
10+
- ES5 지원 중단
11+
- 기본 내보내기(Default Export) 삭제
12+
- Persist 미들웨어가 초기 상태를 바로 스토리지에 저장하지 않음
13+
- use-sync-external-store 패키지가 피어 종속성으로 변경, 필요한 경우 직접 설치
14+
- setState의 상태 대체(replace)가 더욱 엄격하게 동작
15+
16+
## Store
17+
18+
- 애플리케이션의 여러 상태(State, 관리하는 데이터)를 중앙에서 관리하는 패턴
19+
이를 통해 컴포넌트 간 데이터를 쉽게 공유하고 데이터 변경을 감지해 자동으로 렌더링(반응성) 할 수도 있다.
20+
21+
![alt text](image.png)
22+
23+
- 만약 컴포넌트 간에 공유해야 하는 데이터가 있다면 기본적으로 부모와 자식 컴포넌트 간 데이터 전달이 가능하다.
24+
- Props 방식
25+
- 중첩된 컴포넌트 구조에서 불필요하게 데이터를 취급하는 중간 단계의 컴포넌트가 생기고 결합도가 높아지며 유지 보수가 어려워진다.
26+
![alt text](image-1.png)
27+
28+
## Props Drilling
29+
30+
- 이를 피하기 위해 Store 를 사용해서 컴포넌트 간 공유할 데이터를 중앙에서 관리하는데
31+
중간 단계 컴포넌트가 필요치 않으므로 컴포넌트 간 결합도를 낮추고 유지/보수를 쉽게 만든다.
32+
33+
![alt text](image-2.png)
34+
35+
```bash
36+
npm i zustand
37+
```
38+
39+
```tsx
40+
41+
import { create } from 'zustand';
42+
{/*store 생성
43+
콜백은 set, get 매개변수를 가지고 이를 통해 상태 변경 및 조회가 가능하다.
44+
create 함수의 콜백이 반환하는 객체에서의 속성은 state 이고 메소드는 action이다.
45+
create 함수 호출에서 반환하는 스토어 훅(Hook)은 useCountStore와 같이 use접미사, Store 접미사로 명명해서 각 컴포넌트에서 사용 가능하다.
46+
*/}
47+
export const use__Store = create((set, get) => {
48+
return {
49+
상태: initValue,
50+
action: function () => {
51+
const state = get()
52+
const {상태} = state
53+
set({
54+
상태 : 상태 + 1
55+
})
56+
}
57+
}
58+
})
59+
```
60+
61+
```tsx
62+
import { create } from "zustand";
63+
64+
export const use이름Store = create((set) => {
65+
return {
66+
상태: initValue,
67+
action: () => {
68+
set((state) => ({
69+
상태: state.상태 + 1,
70+
}));
71+
},
72+
};
73+
});
74+
```
75+
76+
- get함수를 호출하면 상태와 액션을 가진 store 객체(state)를 얻을 수 있다.
77+
- set함수를 호출(변경할 상태를 속성으로 포함한 객체를 전달)하면 상태를 변경할 수 있다.
78+
- set함수를 호출할 때 콜백을 사용하면 get함수를 사용하지 않아도 바로 store 객체 얻을 수 있다.
79+
- 변경할 상태를 속성으로 포함한 객체를 콜백에서 반환해야 한다.
80+
81+
```tsx
82+
import { create } from "zustand";
83+
84+
export const useCountStore = create<{
85+
count: number;
86+
increase: () => void;
87+
decrease: () => void;
88+
}>((set) => ({
89+
count: 1,
90+
increase: () => set((state) => ({ count: state.count + 1 })),
91+
decrease: () => set((state) => ({ count: state.count - 1 })),
92+
}));
93+
```
94+
95+
생성한 스토어를 다음과 같이 컴포넌트에서 사용할 수 있다.
96+
97+
```tsx
98+
import { useCountStore } from "./store/count";
99+
100+
export default function App() {
101+
const count = useCountStore((state) => state.count);
102+
const increase = useCountStore((state) => state.increase);
103+
const decrease = useCountStore((state) => state.decrease);
104+
return (
105+
<>
106+
<h2>{count}</h2>
107+
<button onClick={increase}>+1</button>
108+
<button onClick={decrease}>-1</button>
109+
</>
110+
);
111+
}
112+
```
113+
114+
## 다중 상태 선택 (useShallow)
115+
116+
- useShallow 훅을 사용하면 여러 상태(액션)을 한번에 객체나 배열로 가져올 수 있다.
117+
- store hook에서 Zustand의 useShallow 훅 중첩 호출해 선택자 함수를 전달한다.
118+
- 이때 선택자 함수는 사용하고자 하는 상태(액션)을 포함하는 객체나 배열을 반환해야 한다.
119+
120+
```ts
121+
import { useShallow } from "zustand/shallow";
122+
123+
const { 상태, 액션 } = use이름Store(
124+
useShallow((state) => ({
125+
상태: state.상태,
126+
액션: state.액션,
127+
}))
128+
// 또는 배열로 한꺼번에 가져온다.
129+
// useShallow(state => [state.상태, state.액션])
130+
);
131+
```
132+
133+
- `count`, `increase`, `decrease` 상태(액션)을 하나씩 가져오지 않고 한꺼번에 가져온다.
134+
- 객체 구조 분해 할당으로 사용할 상태만 가져올 수도 있고 한번에 객체로 모아 처리하는 경우도 있다.
135+
136+
```tsx
137+
import { useShallow } from "zustand/shallow";
138+
import { useCountStore } from "./store/count";
139+
140+
export default function App() {
141+
// const count = useCountStore(state => state.count)
142+
// const increase = useCountStore(state => state.increase)
143+
// const decrease = useCountStore(state => state.decrease)
144+
145+
// const { count, increase, decrease } = useCountStore(state => ({
146+
const countState = useCountStore(
147+
useShallow((state) => ({
148+
count: state.count,
149+
increase: state.increase,
150+
decrease: state.decrease,
151+
}))
152+
// 또는 한번에 배열로 가져온다.
153+
// const countState = useCountStore(
154+
//useShallow(state => [state.count, state.increase, state.decrease]))
155+
);
156+
return (
157+
<>
158+
<h2>{countState.count}</h2>
159+
<button onClick={countState.increase}>+1</button>
160+
<button onClick={countState.decrease}>-1</button>
161+
</>
162+
);
163+
}
164+
```
165+
166+
## 액션 분리
167+
168+
- 여러 컴포넌트에서 단일 스토어의 액션을 많이 사용한다면 액션을 분리해 관리하는 패턴을 활용한다.
169+
- actions 객체 안에서 모든 액션을 관리하면 각 컴포넌트에서 필요한 액션만 가져오기 쉽다.
170+
171+
```ts
172+
import { create } from "zustand";
173+
174+
export const useCountStore = create<{
175+
count: number;
176+
actions: {
177+
increase: () => void;
178+
decrease: () => void;
179+
};
180+
}>((set) => ({
181+
count: 1,
182+
actions: {
183+
increase: () => set((state) => ({ count: state.count + 1 })),
184+
decrease: () => set((state) => ({ count: state.count - 1 })),
185+
},
186+
}));
187+
```
188+
189+
```tsx
190+
import { useCountStore } from "./store/count";
191+
192+
export default function App() {
193+
const count = useCountStore((state) => state.count);
194+
const { increase, decrease } = useCountStore((state) => state.actions);
195+
return (
196+
<>
197+
<h2>{count}</h2>
198+
<button onClick={increase}>+1</button>
199+
<button onClick={decrease}>-1</button>
200+
</>
201+
);
202+
}
203+
```
204+
205+
[도움](https://www.heropy.dev/p/n74Tgc)

zustand/package-lock.json

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zustand/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"zustand": "^5.0.8"
4+
}
5+
}

0 commit comments

Comments
 (0)