์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

๐Ÿ“Œ ์ƒํƒœ(State)๋ž€?

๊ฐ„๋‹จํžˆ ๋งํ•ด, UI๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ React์—์„œ๋Š” ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋ฉด ํ™”๋ฉด์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒํƒœ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•˜๋А๋ƒ๊ฐ€ ์„ฑ๋Šฅ๊ณผ ๊ฐ€๋…์„ฑ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นจ.

๐Ÿ“‚ ์ƒํƒœ์˜ ์ข…๋ฅ˜

1. ์ง€์—ญ ์ƒํƒœ (Local State)

  • ํŠน์ • ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ๋งŒ ๊ด€๋ฆฌ๋˜๋Š” ์ƒํƒœ
  • ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ ๊ณต์œ ํ•˜์ง€ ์•Š์Œ
  • ์˜ˆ : ์ž…๋ ฅ์ฐฝ์˜ ๊ฐ’, ์ฒดํฌ๋ฐ•์Šค ์ƒํƒœ, ๋ชจ๋‹ฌ ์—ด๋ฆผ ์—ฌ๋ถ€ ๋“ฑ

2. ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ์ƒํƒœ (Shared State)

  • ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์ƒํƒœ
  • ๋ณดํ†ต ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ props ์ „๋‹ฌ
  • ์ด ๊ณผ์ •์—์„œ props drilling ๋ฐœ์ƒ
    props drilling : ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š” ์—†๋Š” ์ค‘๊ฐ„ ์ปดํฌ๋„ŒํŠธ๋“ค๊นŒ์ง€ props๋ฅผ ๊ฑฐ์ณ์•ผ ํ•˜๋Š” ์ƒํ™ฉ

3. ์ „์—ญ ์ƒํƒœ (Global State)

  • ํ”„๋กœ์ ํŠธ ์ „์ฒด์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ
  • ๋ถ€๋ชจ์—์„œ ์ž์‹์œผ๋กœ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ (props drilling ๋ฐฉ์‹ ํ™œ์šฉ)
  • ์˜ˆ : ์‚ฌ์šฉ์ž ์ •๋ณด, ํ…Œ๋งˆ ์„ค์ •, ๋‹ค๊ตญ์–ด ์„ค์ •, ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ๋“ฑ

โš ๏ธ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

  • ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋ฉด ์ง์ ‘์ ์ธ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ด ์–ด๋ ค์›€
  • ์ „์—ญ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด, ๊ฒฐ๊ตญ props drilling ์ด ์‹ฌํ•ด์ ธ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง

๐ŸŒ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ์Œ.

์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹ค์–‘ํ•˜์ง€๋งŒ, Context API(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์•„๋‹ˆ์ง€๋งŒ, React ๊ธฐ๋ณธ ์ œ๊ณต), Redux(npm trends 1์œ„), Recoil(ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ ๊ฒฝํ—˜), Zustand(์•ž์œผ๋กœ ์‚ฌ์šฉ ์˜ˆ์ •) ์ด 4๊ฐ€์ง€ ๋น„๊ต

๐Ÿ“Œ Context API

React ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ์•ˆ์—์„œ ์ „์—ญ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ง„ ๋ฐฉ๋ฒ•.
๋‹ค๋งŒ, ๋ณธ์งˆ์ ์œผ๋กœ๋Š” ์ข…์†์„ฑ ์ฃผ์ž…์„ ์œ„ํ•œ ๋„๊ตฌ์ด๊ธฐ ๋•Œ๋ฌธ์—, Redux๋‚˜ Recoil ๊ฐ™์€ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ํˆด์ด๋ผ๊ณ  ํ•˜๊ธฐ ๋‹ค์†Œ ์• ๋งค

โญ๏ธ Context API๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ƒํƒœ๋ฅผ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋“ค๊ณผ ์‰ฝ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ•  (์ „์—ญ ์ƒํƒœ ๊ณต์œ )

Context API ๊ตฌ์„ฑ

  1. Context
    • ์ „์—ญ ์ƒํƒœ์˜ ์ €์žฅ์†Œ ๊ฐ™์€ ๊ฐœ๋…
    • createContext()๋กœ ์ƒ์„ฑ
    • ๋‚ด๋ถ€์— Provider์™€ Consumer ์ •์˜
    • Consumer๋Š” Context ํ†ตํ•ด ์ƒํƒœ์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
  2. Provider
    • Context์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ธ‰ํ•˜๋Š” ์—ญํ• 
    • value ์†์„ฑ์— ์ „๋‹ฌํ•œ ๊ฐ’์ด ์ „์—ญ ์ƒํƒœ๋กœ ๊ณต์œ ๋จ
    • ๋ณดํ†ต ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ •์˜
  3. Consumer
    • Provider๊ฐ€ ์ œ๊ณตํ•œ ์ „์—ญ ์ƒํƒœ๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ์—ญํ• 
    • ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๊ฐ€ Hooks๋ฅผ ์“ฐ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ฃผ๋กœ ์‚ฌ์šฉ
    • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” useContext๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ
    • Provider์˜ value๋ฅผ ๋ฐ›์•„ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ
  4. useContext (Hook)
    • ์ตœ๊ทผ์—๋Š” Consumer ๋Œ€์‹  useContext ํ›…์„ ์จ์„œ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ

Context API ์˜ˆ์‹œ

  • src / store / context / useCounterContext.tsx

  • src / pages / context / ContextPage.tsx

  • src / pages / context / components / CounterDisplay.tsx

  • src / pages / context / components / CounterButtons.tsx

โœ… ์žฅ์ 

  • React ๊ธฐ๋ณธ ์ œ๊ณต์œผ๋กœ ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ์—†์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ.
  • ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๋น„๊ต์  ๋‹จ์ˆœํ•˜์—ฌ ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ๋‚ฎ์Œ.

โŒ ๋‹จ์ 

  • Provider์—์„œ value๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ด๋‹น Context๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง.
  • ์ƒํƒœ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก Context ํŒŒ์ผ์ด ์ปค์ง€๊ณ , ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง.
  • ์ค‘์ฒฉ Provider ๊ฐ€๋…์„ฑ ์ €ํ•˜.

๐Ÿ“Œ Redux

React์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
ํŠน์ง•์€ ๊ธฐ์กด state๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ , ์ƒˆ๋กœ์šด state๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์—…๋ฐ์ดํŠธ
์ƒํƒœ ๋ณ€๊ฒฝ์€ ๋ฐ˜๋“œ์‹œ Action์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ด๋ฃจ์–ด์ง€๊ณ , ์ด Action์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜์ธ Reducer๋ฅผ ๊ฑฐ์ณ ์ฒ˜๋ฆฌ๋˜๋Š”๋ฐ, ์ด ๊ณผ์ • ๋•๋ถ„์— ์–ด๋–ค ์ƒํƒœ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ•˜๋Š”์ง€ ์˜ˆ์ธก ๊ฐ€๋Šฅ

Redux ์ƒํƒœ ๋ณ€๊ฒฝ ๊ฒฝ๋กœ

  • ๊ธฐ์กด ๋ฐฉ์‹ (props drilling)
    A โ†’ B โ†’ C โ†’ D โ†’ E โ†’ F โ†’ G

  • Redux ๋ฐฉ์‹
    A โ†’ Store โ†’ G
    Store๋ฅผ ํ†ตํ•ด ๋ฐ”๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋ถˆํ•„์š”ํ•œ props ์ „๋‹ฌ์ด ์‚ฌ๋ผ์ง€๊ณ  ์ƒํƒœ๋ฅผ ์ง์ ‘ ์ฝ๊ณ  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด ํ›จ์”ฌ ํšจ์œจ์ 

Redux ๊ตฌ์„ฑ

  1. Store
    • ์ƒํƒœ๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ์ค‘์•™ ๊ณต๊ฐ„
    • ์ปดํฌ๋„ŒํŠธ์™€๋Š” ๋ณ„๊ฐœ๋กœ ์กด์žฌ
    • ํ•„์š”ํ•œ ์ƒํƒœ Store ์•ˆ์— ๋‹ด๊ณ , ์ปดํฌ๋„ŒํŠธ๋Š” Store์—์„œ ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ด
  2. Action
    • ์ƒํƒœ ๋ณ€๊ฒฝ ์š”์ฒญ ๊ฐ์ฒด
    • ์ผ๋ฐ˜์ ์œผ๋กœ { type: "INCREASE", payload: 1 } ํ˜•์‹
    • dispatch() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด Store์— ์ „๋‹ฌ
  3. Reducer
    • ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๋งŒ๋“œ๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜
    • (state, action) => newState ํ˜•ํƒœ
    • ๊ธฐ์กด state๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ , ์ƒˆ๋กœ์šด state ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
    • action์˜ type์— ๋”ฐ๋ผ state ์—…๋ฐ์ดํŠธ

Redux ์˜ˆ์‹œ

โญ๏ธ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์— Provider๋กœ store๋ฅผ ์ „์—ญ์œผ๋กœ ๊ณต๊ธ‰ํ•ด์•ผ ์ปดํฌ๋„ŒํŠธ๋“ค์ด Redux๋ฅผ ์‚ฌ์šฉ

  • src / Main.tsx

  • src / store / redux / counterSlice.ts

  • src / store / redux / store.ts

  • src / store / redux / ReduxPage.tsx

  • src / store / redux / CounterDisplay.tsx

  • src / store / redux / CounterButtons.tsx

โœ… ์žฅ์ 

  • ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ 1์œ„.
  • ๋ชจ๋“  ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ action์œผ๋กœ ์ •์˜ํ•˜๊ณ  action ์ •๋ณด์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ reducer ์—์„œ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ๋ฅผ ์‰ฝ๊ฒŒ ์˜ˆ์ธก ๊ฐ€๋Šฅ.
  • Redux DevTools ๋ฅผ ํ†ตํ•ด ์ƒํƒœ ๊ด€๋ฆฌ์˜ ๋””๋ฒ„๊น…์ด ํŽธ๋ฆฌ

โŒ ๋‹จ์ 

  • Hook ๊ธฐ๋ฐ˜์ด ์•„๋‹˜.
  • ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•˜๊ณ  ๋Ÿฌ๋‹์ปค๋ธŒ๊ฐ€ ๋†’์Œ.
  • ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ ๋งŽ์Œ.
  • ๋น„๋™๊ธฐ ์š”์ฒญ์„ ์œ„ํ•œ Redux-thunk, Redux-Saga ๋“ฑ์˜ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”.

๐Ÿ“Œ Recoil

Facebook์—์„œ ๊ฐœ๋ฐœํ•œ React ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉ๋ฐฉ์‹์€ useState ์™€ ๋งค์šฐ ๋น„์Šท.
ํŠน์ง•์€ ์ƒํƒœ๋ฅผ atom ๋‹จ์œ„๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ํ•ด๋‹น ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ตœ์†Œํ™”
ํŒŒ์ƒ ์ƒํƒœ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” selector ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ง€์›ํ•˜์—ฌ ์ž…๋ ฅ์ด ๊ฐ™์œผ๋ฉด ์ด์ „์— ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ
๋˜ํ•œ ๋ณ„๋„์˜ ์ถ”๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ๋น„๋™๊ธฐ ์ƒํƒœ ๊ด€๋ฆฌ ์ง€์›.

Recoil ๊ตฌ์„ฑ

Atom, Hooks, Selector

  1. Atom
    • Recoil์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ํ•˜๋‚˜์˜ ์ƒํƒœ ๋‹จ์œ„
    • ๊ณ ์œ ํ•œ key์™€ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •
    • ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ด๋‹น atom์„ ๊ตฌ๋…ํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง
    • ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ตฌ๋… ์ค‘์ธ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฆฌ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Œ useRecoilState (Hook)
  2. useRecoilState (Hook)
    • useState์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ atom ๊ฐ’์„ ์ฝ๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ํ›…
  3. useRecoilValue (Hook)
    • atom์˜ ๊ฐ’์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ํ›…
  4. useSetRecoilState (Hook)
    • atom ๊ฐ’์„ ์ˆ˜์ • ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ํ›…
  5. Selector
    • atom์—์„œ ํŒŒ์ƒ๋œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ฑฐ๋‚˜ ๊ฐ€๊ณตํ•˜๋Š” ํ•จ์ˆ˜
    • ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ†ตํ•ด ๋™์ผํ•œ ์ž…๋ ฅ ๊ฐ’์ด๋ฉด ์ด์ „ ๊ณ„์‚ฐ ๊ฐ’์„ ์žฌ์‚ฌ์šฉ
    • ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋„ ๊ฐ€๋Šฅ

Recoil ์—์‹œ

โญ๏ธ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์— <RecoilRoot>๋กœ ๊ฐ์‹ธ ์ดˆ๊ธฐ ์„ธํŒ…

  • src / Main.tsx

  • src / store / recoil / counterRecoil.ts

  • src / store / recoil / RecoilPage.tsx

  • src / pages / recoil / components / CounterDisplay.tsx

  • src / pages / recoil / components / CounterButtons.tsx

โœ… ์žฅ์ 

  • useState ํ›…๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•˜์—ฌ ์ง๊ด€์ ์ด๊ณ  ๊ฐ„๋‹จํ•œ ๊ตฌ์กฐ
  • Selector๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅ

โŒ ๋‹จ์ 

  • redux ์ฒ˜๋Ÿผ ๋”ฐ๋กœ ๋””๋ฒ„๊น…ํˆด์ด ์—†์–ด ์ƒ๋Œ€์ ์œผ๋กœ ๋ถˆํŽธ
  • ์ „์—ญ ์ƒํƒœ์— ์–ด๋””์„œ๋“  ์ง์ ‘ ์ ‘๊ทผํ•ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด, ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ์ œ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋Š”์ง€ ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ค์›€.
  • ์˜์กด์„ฑ์ด ์—ฌ๋Ÿฌ ๋ฐฉํ–ฅ์œผ๋กœ ์—ฎ์ด๋ฉด์„œ ์ ์  ์˜ˆ์ธก ๋ถˆ๊ฐ€

๐Ÿ“Œ Zustand

Redux์™€ ๊ฐ™์€ Flux ํŒจํ„ด(Action โ†’ Dispatcher โ†’ Store โ†’ View)์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ํ›จ์”ฌ ๊ฐ„์†Œํ™”๋œ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.
์ž‘๊ณ  ๋น ๋ฅด๋ฉฐ ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ณ  React Hooks ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง.

ํŠน์ง•์€ ํด๋กœ์ €๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์Šคํ† ์–ด ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ข…์†๋˜์ง€ ์•Š๊ณ , ๋ฐ”๋‹๋ผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

Zustand ์„ค์น˜

yarn add zustand

Zustand ์˜ˆ์‹œ

  • ๊ธฐ๋ณธ ์‚ฌ์šฉ
    • create ํ•จ์ˆ˜๋กœ ์Šคํ† ์–ด ์ƒ์„ฑ
    • create ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ์€ set, get ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ์Œ.
    • create ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด์—์„œ์˜ ์†์„ฑ์€ ์ƒํƒœ(State)์ด๊ณ , ๋ฉ”์†Œ๋“œ๋Š” ์•ก์…˜(Action) ์ด๋ผ๊ณ  ํ•จ.
    • create ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์Šคํ† ์–ด ํ›…(Hook)์€,
      useCounterStore ๊ฐ™์ด use ์ ‘๋‘์‚ฌ + ์ด๋ฆ„ + Store ์ ‘๋ฏธ์‚ฌ๋กœ ๋ช…๋ช…ํ•ด์„œ ๊ฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ
1
2
3
4
5
6
7
8
import { create } from 'zustand'

export const use์ด๋ฆ„Store = create((set, get) => {
  return {
    ์ƒํƒœ: ์ดˆ๊นƒ๊ฐ’,
    ์•ก์…˜: ํ•จ์ˆ˜
  }
})
  • src / store / zustand / useCounterStore.ts
    • set, get ๋งค๊ฐœ๋ณ€์ˆ˜(ํ•จ์ˆ˜)๋Š” ์•ก์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
    • get ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ƒํƒœ์™€ ์•ก์…˜์„ ๊ฐ€์ง„ ์Šคํ† ์–ด ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ.
    • set ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ.
    • set ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜๋ฉด, get ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋ฐ”๋กœ ์Šคํ† ์–ด ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ. ๋ณ€๊ฒฝํ•  ์ƒํƒœ๋ฅผ ์†์„ฑ์œผ๋กœ ํฌํ•จํ•œ ๊ฐ์ฒด๋ฅผ ์ฝœ๋ฐฑ์—์„œ ๋ฐ˜ํ™˜

  • src / pages / zustand / ZustandPage.tsx

  • src / pages / zustand / components / CounterDisplay.tsx
    • ์ปดํฌ๋„ŒํŠธ์—์„œ ์Šคํ† ์–ด ํ›…(use์ด๋ฆ„Store)์„ ๊ฐ€์ ธ์™€ ํ˜ธ์ถœํ•  ๋•Œ ์„ ํƒ์ž ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ด ์›ํ•˜๋Š” ์ƒํƒœ๋‚˜ ์•ก์…˜์„ ์–ป์„ ์ˆ˜ ์žˆ์Œ.
    • ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง
    • ๊ฐ™์€ ์Šคํ† ์–ด์˜ ๋‹ค๋ฅธ ์ƒํƒœ๋ฅผ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋„๋ก, ํ•œ ๋ฒˆ์˜ ํ›… ํ˜ธ์ถœ๋กœ ํ•˜๋‚˜์˜ ์ƒํƒœ๋งŒ ๊ฐ€์ ธ์™€์•ผํ•จ.

  • src / pages / zustand / components / CounterButtons.tsx

  • ์ฃผ์˜ ์‚ฌํ•ญ
    • ์„ ํƒ์ž ํ•จ์ˆ˜ ์—†์ด ์Šคํ† ์–ด ํ›…์„ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐœ๋ณ„ ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ์Šคํ† ์–ด ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ.
    • ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ํ•ด๋‹น ์Šคํ† ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜

โœ… ์žฅ์ 

  • redux์˜ Redux DevTools ๋กœ ๋””๋ฒ„๊น… ๊ฐ€๋Šฅ.
  • ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ๊ฐ์†Œ.
  • Provider๋กœ ๊ฐ์‹ธ์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœ.
  • React Hook์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ Hook ํ•„์š” ์—†์Œ.

โŒ ๋‹จ์ 

  • Redux๋ณด๋‹ค ๋ณด์กฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ๋ถ€์กฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๋ณด์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์ˆ˜๋‹จ์ด ํ•„์š” (React Query)

โญ๏ธ ์‚ฌ์šฉ์ž ์ˆ˜ ์ฆ๊ฐ€์— ๋”ฐ๋ฅธ ์ฃผ์˜์‚ฌํ•ญ

์‚ฌ์šฉ์ž ์ˆ˜ ๊ฐ€ ์ฆ๊ฐ€ํ•œ๋‹ค๊ณ  ํ•ด์„œ zustand ์ž์ฒด์— ์„ฑ๋Šฅ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹˜.
ํ•˜์ง€๋งŒ zustand๋ฅผ ๋‹จ๋…์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉ์ž ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋กœ๋Š”

  • ์„œ๋ฒ„ ๋ถ€ํ•˜์™€์˜ ์—ฐ๋™ ๋ฌธ์ œ
    • zustand ๋Š” ์„œ๋ฒ„ ์ƒํƒœ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์šฉ์ž ์ˆ˜๊ฐ€ ๋Š˜๋ฉด API ํ˜ธ์ถœ ํšŸ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚จ.
    • ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ์„œ๋ฒ„ ๋ถ€ํ•˜๊ฐ€ ์ปค์ง€๊ณ , ์บ์‹ฑ/๋™๊ธฐํ™” ๋กœ์ง์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด ์ค‘๋ณต ์š”์ฒญ ๋ฌธ์ œ ๋ฐœ์ƒ.

โ†’ ํŠธ๋ž˜ํ”ฝ ๊ด€๋ จ ๋ฌธ์ œ๋Š” React Query๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ๊ธฐ๋Œ€ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Œ.
์บ์‹ฑ, ์ค‘๋ณต ์š”์ฒญ ์ œ๊ฑฐ, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌํŒจ์นญ, ์ž๋™ ๋ฆฌํŠธ๋ผ์ด ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ์žˆ์–ด ์„œ๋ฒ„ ์ƒํƒœ ๊ด€๋ฆฌ ๋ถ€๋‹ด์ด ์ค„์–ด๋“ฌ

  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์ฆ๊ฐ€
    • ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ์— zustand store ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ณ„ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด์ด ์ปค์งˆ ์ˆ˜ ์žˆ์Œ.
  • ๋นˆ๋ฒˆํ•œ ์ƒํƒœ ๋ณ€๊ฒฝ
    • ์ƒํƒœ ๋ณ€๊ฒฝ์ด ์ž์ฃผ ์ผ์–ด๋‚˜๋ฉด ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฆฌ๋ Œ๋”๋ง ๋  ์ˆ˜ ์žˆ์Œ (ํด๋ผ์ด์–ธํŠธ ์„ฑ๋Šฅ ์ €ํ•˜ ์ดˆ๋ž˜)

โ†’ ์‚ฌ์šฉ์ž ์ˆ˜์™€๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ์ฝ”๋“œ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ณต์žก์„ฑ์ด ์ปค์ง€๋Š”๊ฒŒ ํ•ต์‹ฌ ๋ฆฌ์Šคํฌ store ๊ตฌ์กฐํ™” ๋˜๋Š” ์›ํ™œํ•œ ํ˜‘์—…์„ ์œ„ํ•ด ํ‘œ์ค€ ๊ตฌ์กฐ๋‚˜ ํŒจํ„ด ์ˆ˜๋ฆฝ ํ•„์š”.

Redux๋Š” ๊ตฌ์กฐ๊ฐ€ ํƒ„ํƒ„ํ•˜์ง€๋งŒ ๋ณต์žกํ•œ ๋ฐ˜๋ฉด,

Recoil์€ ์ง๊ด€์ ์ด๊ณ  ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ๋‚ฎ์•„ ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ์ข‹์•˜์Œ. ๊ทธ๋Ÿฌ๋‚˜ Recoil์€ ์–ด๋А ์ปดํฌ๋„ŒํŠธ์—์„œ๋“  ์ „์—ญ ์ƒํƒœ๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด ์ƒํƒœ ๋ณ€๊ฒฝ ์ถ”์ ์ด ์–ด๋ ต๊ณ , atom์ด ๋งŽ์•„์ง€๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ.

๋”ฐ๋ผ์„œ, Recoil์˜ ์žฅ์ ๊ณผ Redux์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ๊ณผ ๊ตฌ์กฐ์  ์•ˆ์ •์„ฑ์„ ๊ฒฐํ•ฉํ•œ Zustand๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ผ ๊ฒƒ ๊ฐ™์Œ