ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด, ์ปดํฌ๋ํธ ๊ฐ ์ํ๋ฅผ ๊ณต์ ํ๊ณ ๋ณ๊ฒฝ ์ฌํญ์ ์ผ๊ด์ฑ ์๊ฒ ๋ฐ์ํ๋ ๊ฒ์ด ์ค์ํ ๊ณผ์ ๊ฐ ๋๋ค.
์ด๋ฅผ ์ํด ๋ค์ํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์กด์ฌํ๋ฉฐ, ๋ํ์ ์ผ๋ก Redux, Recoil, MobX ๋ฑ์ด ์๋ค. ์ต๊ทผ์๋ ๋ณด๋ค ๋จ์ํ๊ณ ๊ฐ๋ฒผ์ด ์ ๊ทผ ๋ฐฉ์์ ์ ๊ณตํ๋ Zustand๊ฐ ์ฃผ๋ชฉ๋ฐ๊ณ ์๋ค.
1. Zustand๋ ๋ฌด์์ธ๊ฐ
Zustand
zustand-demo.pmnd.rs
Zustand์ ๊ณต์๋ฌธ์์ด๋ค.
๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด,
์๊ณ , ๋น ๋ฅด๋ฉฐ ํ์ฅ ๊ฐ๋ฅํ ์ต์ํ์ ์ํ ๊ด๋ฆฌ ์๋ฃจ์ ์ ๋๋ค.
Zustand๋ ํ (Hooks)์ ๊ธฐ๋ฐํ ํธ์ํ API๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ๋ง๊ฑฐ๋ ํน์ ํ ์๊ฒฌ(opinion)์ ์น์ฐ์น์ง ์์ง๋ง, ๋ช ์์ ์ด๊ณ Flux์ ์ ์ฌํ ๊ตฌ์กฐ๋ฅผ ์ ์งํ ์ ์๋ ์ถฉ๋ถํ ๊ท์น์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ท์ฝ๋ค๊ณ ๋ฌด์ํ์ง ๋ง์ธ์. ๋ฐํฑ์ด ์์ต๋๋ค!
๋ง์ ์๊ฐ์ ๋ค์ฌ ํํ ๊ฒช๋ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ๋ช ๋์ ์ข๋น ์์(zombie child) ๋ฌธ์ , React์ ๋์์ฑ(concurrency), ์๋ก ๋ค๋ฅธ ๋ ๋๋ฌ ๊ฐ์ ์ปจํ ์คํธ ์์ค(context loss) ๋ฑ์ ๋ค๋ฃน๋๋ค.
React ์ํ๊ณ์์ ์ด๋ฌํ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋ ๊ฑฐ์ ์ ์ผํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ผ์ง๋ ๋ชจ๋ฆ ๋๋ค.
๋ผ๊ณ ํ๋ค.
โ๏ธ์ข ํฉํด๋ณด๋ฉด
1. Zustand๋ ํต์ฌ ๊ธฐ๋ฅ๋ง ์ ๊ณตํ๋ ๊ฐ๋ฒผ์ด ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
2. Redux์ฒ๋ผ ๋ณต์กํ ์ค์ ์ด๋ ํ์ผ ๊ตฌ์กฐ ์์ด๋ ์ธ ์ ์๊ณ , ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ ธ๋ ๋ฌด๋ฆฌ ์์ด ํ์ฅํ ์ ์๋ค๋ ์ฅ์
3. React์ useState, useEffect ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค๋ ์๋ฏธ
4. ๋ณต์กํ action, reducer, dispatch ๊ฐ์ ๊ฐ๋
์ ๊ฐ์ ๋ก ์ฐ๊ฒ ํ์ง ์์์ ์ง์
์ฅ๋ฒฝ์ด ๋ฎ์
5. ํน์ ํจํด์ ๊ฐ์ ํ์ง ์์ง๋ง, Flux ์ํคํ
์ฒ์ฒ๋ผ ๋ฐ์ดํฐ ํ๋ฆ์ด ๋จ๋ฐฉํฅ์ด๋ผ ๊ตฌ์กฐ๊ฐ ๋ช
ํํฉ๋๋ค.
6. ์ข๋น ์์ ๋ฌธ์ (zombie child problem)
→ ์ํ๊ฐ ์
๋ฐ์ดํธ๋๋๋ฐ ์ด๋ฏธ ์ธ๋ง์ดํธ๋ ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๋ ๋ฒ๊ทธ๋ฅผ ์๋ฏธํฉ๋๋ค.
7. React ๋์์ฑ(Concurrency)
→ React 18์ concurrent mode์์๋ ์ํ ๊ด๋ฆฌ๊ฐ ์์ ํ๊ฒ ๋์ํ๋๋ก ์ค๊ณ๋จ.
8. ์ปจํ
์คํธ ์์ค(Context loss)
→ React Native, Web, Three.js ๊ฐ์ด ๋ ๋๋ฌ๊ฐ ํผํฉ๋ ํ๊ฒฝ์์๋ ์ํ๋ฅผ ์์ ํ๊ฒ ๊ณต์ ๊ฐ๋ฅ.
์์ฝ: Zustand๋ ๋จ์ํ์ง๋ง ๊น์ด ์๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ณ , React์์ ๋ฐ์ํ๋ ๊น๋ค๋ก์ด ๋ฒ๊ทธ ์ํฉ๋ ๋๋ถ๋ถ ํด๊ฒฐํด์ฃผ๋ ๊ฑฐ์ ์ ์ผํ ์ ํ์ง์ด๋ค
2. ๊ธฐ๋ณธ์ฌ์ฉ๋ฐฉ๋ฒ
import { create } from 'zustand'
const useStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
updateBears: (newBears) => set({ bears: newBears }),
}))
function BearCounter() {
const bears = useStore((state) => state.bears)
return <h1>{bears} bears around here...</h1>
}
function Controls() {
const increasePopulation = useStore((state) => state.increasePopulation)
return <button onClick={increasePopulation}>one up</button>
}
1. create()
• Zustand ์คํ ์ด๋ฅผ ๋ง๋๋ ์ต์ด ํจ์.
• ์ธ์๋ก ์ ๋ฌํ๋ ํจ์ ์์์ ์ํ(state)์ ์ํ ๋ณ๊ฒฝ ๋ก์ง(setter)์ ์ ์ํฉ๋๋ค.
2. set()
• ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์.
• ๋ถ๋ถ ์
๋ฐ์ดํธ ๊ฐ๋ฅ(merge ๋์).
3. get()
• ์คํ ์ด์ ํ์ฌ ์ํ๋ฅผ ์ฆ์ ์ฝ๋ ํจ์.
• React ํ
์์ด๋ ์ธ๋ถ์์ ์ํ๋ฅผ ์ฝ์ ์ ์์.
4. subscribe()
• ํน์ ์ํ ๋ณํ์ ๋ํด ๋ฆฌ์ค๋ ๋ฑ๋ก.
• React ์ปดํฌ๋ํธ ๋ฐ๊นฅ์์๋ ์ํ ๋ณํ๋ฅผ ๊ฐ์ง ๊ฐ๋ฅ.
const unsubscribe = useStore.subscribe(state => {
console.log('count changed:', state.count);
});
unsubscribe(); // ๊ตฌ๋
ํด์
๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค๊ณผ์ ์ฐจ์ด์ (Zustand vs ๋ค๋ฅธ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋น๊ต)
Zustand | Redux | Recoil | Jotai | |
์ฒ ํ | ์ต์ํ์ API, ๊ฐ๋ฐ์๊ฐ ์ง์ ํจํด ์ค๊ณ | Flux ์ํคํ ์ฒ ๊ธฐ๋ฐ, ๊ฐ๋ ฅํ ๊ท์น๊ณผ ๋ณด์ผ๋ฌํ๋ ์ดํธ | React ์ํ๋ฅผ ์ ์ญ์ ์ผ๋ก ๋ค๋ฃจ๋ Declarative ๋ชจ๋ธ | ์์(atom) ๋จ์๋ก ์ํ ๊ด๋ฆฌ, React Hooks ์นํ์ |
๋ณด์ผ๋ฌํ๋ ์ดํธ | ๊ฑฐ์ ์์ | ๋ง์(์ก์ , ๋ฆฌ๋์, ์คํ ์ด ์ค์ ๋ฑ) | ์ ์ | ๊ฑฐ์ ์์ |
ํ์ต ๊ณก์ | ๋ฎ์ | ์ค๊ฐ~๋์ | ์ค๊ฐ | ๋ฎ์ |
๋น๋๊ธฐ ์ฒ๋ฆฌ | ์์ ๋กญ๊ฒ ๊ตฌํ(๋ฏธ๋ค์จ์ด ํจํด ์๋) | ๋ฏธ๋ค์จ์ด(thunk, saga ๋ฑ) ํ์ | Suspense ๊ธฐ๋ฐ ๋น๋๊ธฐ ์ง์ | Suspense ๊ธฐ๋ฐ ๋น๋๊ธฐ ์ง์ |
๋ฆฌ๋ ๋๋ง ์ ์ด | selector ๊ธฐ๋ฐ์ผ๋ก ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋ ์ต์ํ | connect ๋๋ hooks์์ memoization ํ์ | ํํธํ๋ atom ๋จ์๋ก ์ต์ํ | atom ๋จ์๋ก ์ต์ํ |
React ์์กด์ฑ | ๋ฎ์(React ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ) | ๋์ | ๋์ | ๋์ |
์คํ ์ด ๊ตฌ์กฐ | ๋จ์ผ ์คํ ์ด or ๋ค์ค ์คํ ์ด ๋ชจ๋ ๊ฐ๋ฅ | ์ฃผ๋ก ๋จ์ผ ์คํ ์ด | atom๋ค์ ์งํฉ | atom๋ค์ ์งํฉ |
SSR ์ง์ | ์ฌ์ | ์ฌ์ | ์ผ๋ถ ์ผ์ด์ค ๊ณ ๋ ค ํ์ | ์ฌ์ |
์ฐ๋ฆฌ ํ์ ํ์ฌ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ณผ๋๊ธฐ๋ฅผ ๊ฒช๊ณ ์๋ค.
๊ณผ๊ฑฐ ํ๋ก์ ํธ ์๊ตฌ์ฌํญ๊ณผ ํ์์ ์ ํธ๋ ์ฐจ์ด๋ก ์ธํด Jotai, Redux, Recoil์ด ํผํฉ๋ ๊ตฌ์กฐ๊ฐ ํ์ฑ๋์๊ณ , ๊ทธ ๊ฒฐ๊ณผ ์ ์ญ ์ํ์ ํ๋ฆ์ด ๋ณต์กํด์ง๊ณ ์ ์ง๋ณด์๊ฐ ์ ์ ์ด๋ ค์์ก๋ค.
์ด์ ๋ฐ๋ผ ์ฐ๋ฆฌ๋ ์ํ๊ด๋ฆฌ ๋ฐฉ์์ Zustand๋ก ํตํฉํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค.
Zustand๋ ๋น๊ต์ ๊ฐ๋ฒผ์ฐ๋ฉด์๋ ๋ช
์์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ๋ฏ๋ก, ๊ธฐ์กด์ ๋ถ์ฐ๋ ์ํ๋ฅผ ํ ๊ณณ์ผ๋ก ๋ชจ์ผ๊ธฐ์ ์ ํฉํ๋ค๊ณ ํ๋จํ๋ค.
๋ค๋ง, ํตํฉ ๊ณผ์ ์์ ๊ณ ๋ คํด์ผ ํ ์ค์ํ ์ ์ด ์๋ค.
ํ์ฌ Redux์์๋ ๋น๋๊ธฐ์ ๋ผ์ฐํ
์ฒ๋ฆฌ ๋ก์ง์ด ์ ์ญ์์ ๊ด๋ฆฌ๋๊ณ ์๋๋ฐ, ์ด ๊ธฐ๋ฅ์ ๋จ์ํ Zustand๋ก ์ฎ๊ธฐ๋ ๊ฒ๋ง์ผ๋ก๋ ๋์ผํ ์ ์ฐ์ฑ์ ํ๋ณดํ๊ธฐ ์ด๋ ต๋ค.
Zustand์์๋ ์ด๋ฌํ ๋น๋๊ธฐ ํ๋ฆ์ ๋ฏธ๋ค์จ์ด ๋๋ subscribe ๊ธฐ๋ฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ก ์ฌ๊ตฌ์ฑํด์ผ ํ๋ฉฐ, ์ํ ๋ณ๊ฒฝ๊ณผ ๋ผ์ฐํ
์ ํ์ด ๋๊น ์์ด ๋์ํ๋๋ก ์ค๊ณํ๋ ๊ฒ์ด ํต์ฌ ๊ณผ์ ์๋ค.
๋ค์ ๊ธ์์๋ ์ด๋ป๊ฒ ์ด๋ฌํ ๊ณผ์ ๋ค์ ์ ์ฉ์์ผฐ๋์ง ์จ๋ณด๋๋ก ํ๊ฒ ๋ค!
'Developing๐ฉโ๐ป > Front-end' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[FE] Webpack, Rollup.js, ๊ทธ๋ฆฌ๊ณ Vite (0) | 2025.08.22 |
---|---|
SPA๋ก UX๋ฅผ ๊ฐ์ ํ๋ ํจ๊ณผ์ ์ธ ์ ๋ต๋ค- ์๋ฌธ ๋ฒ์ญ (0) | 2025.08.19 |
[FE] ๋์์ธ์์คํ FSD ์ํคํ ์ณ๋ก ์์ ํ๊ธฐ(..ing) (3) | 2025.08.12 |
[ํ๋ก ํธ์๋ ๋์์ธํจํด] 1. ์ฑ๊ธํด ํจํด(Singleton Pattern) (3) | 2025.08.07 |
[JS] ํจ์ ์์๋ก ์ดํด๋ณด๋ static ๋ฉ์๋ ํ์ฉ๋ฒ (1) | 2025.07.13 |