๐Ÿงฑ 02. ํ•ต์‹ฌ ๊ฐœ๋…๊ณผ ๊ธฐ๋ณธ ์Šคํ† ์–ด ์„ค๊ณ„: "์ด ์Šคํ† ์–ด, ๋„ˆ๋ฌด ๋ฌด๊ฒ์ง€ ์•Š๋‚˜์š”?"

๐Ÿ“‹ ๊ฐœ์š”

Zustand์˜ create, set, get ํŒจ๋Ÿฌ๋‹ค์ž„๊ณผ ๋ถˆ๋ณ€์„ฑ ๋ฉ˜ํƒˆ ๋ชจ๋ธ

๐ŸŽฏ ์ด ์„น์…˜์„ ์ฝ๊ณ  ๋‚˜๋ฉด:

  • Zustand์˜ create, set, get ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Zustand set ์˜ ์–•์€ ๋ณ‘ํ•ฉ๊ณผ ์ค‘์ฒฉ ๊ฐ์ฒด(Nested Objects) ์—…๋ฐ์ดํŠธ ์‹œ ๋ถˆ๋ณ€์„ฑ ๊ทœ์น™์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 10๋ถ„ / ํ•ต์‹ฌ ํŒŒํŠธ: 6๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
์Šคํ† ์–ด ์ƒ์„ฑ ์›๋ฆฌ(create) โ†’ ์–•์€ ๋ณ‘ํ•ฉ ์—…๋ฐ์ดํŠธ(set) โ†’ ๋น„๋™๊ธฐ ๋กœ์ง ๋‚ด ์ƒํƒœ ์ฐธ์กฐ(get)

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜! Zustand ๋ชจ๋ธ๋ง ์—„์ฒญ ์ง๊ด€์ ์ด๋„ค์š”. ์‹ ๋‚˜์„œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์•ฑ์— ์žˆ๋Š” ์œ ์ € ์ •๋ณด, ๊ฒŒ์‹œ๊ธ€ ๋ฆฌ์ŠคํŠธ, UI ํ…Œ๋งˆ, ๊ธ€ ์ž‘์„ฑ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋‹ค useAppStore ํ•˜๋‚˜์— ๋•Œ๋ ค ๋ฐ•์•˜์–ด์š”! ์–ด๋ผ, ๊ทผ๋ฐ ์˜์ˆ˜ ๋‹˜์ด PR ๋ณด์‹œ๋”๋‹ˆ '์™œ ์Šคํ† ์–ด๊ฐ€ ๋ชจ๋†€๋ฆฌ์‹ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋งˆ๋ƒฅ ๋ฌด๊ฒ๋ƒ'๊ณ  ๋ฆฌ๋ทฐ๋ฅผ ๋‹ค์…จ์–ด์š”..."
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, ์ „์—ญ์œผ๋กœ ๋บ€ ๊ฑฐ๊นŒ์ง„ ์ข‹์•˜์–ด์š”. ๊ทธ๋Ÿฐ๋ฐ Zustand์˜ ์ง„์งœ ๊ฐ•๋ ฅํ•จ์€ ๊ทธ ๊ฐ€๋ฒผ์šด create ํ•จ์ˆ˜ ์•ˆ์— ์žˆ์–ด์š”. ๊ฐ์ฒด๋ฅผ ๋šฑ๋šฑํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด ๊ด€๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ๋Š˜์–ด๋‚˜๊ณ , ๋ถˆ๋ณ€์„ฑ(Immutability) ์—…๋ฐ์ดํŠธ๋„ ์ ์  ๊นŠ์ด ๋“ค์–ด๊ฐ€๋Š” ๋Šช(Depth Hell)์ด ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋ผˆ๋Œ€์ธ set๊ณผ get๋ถ€ํ„ฐ ๋‹จ๋‹จํ•˜๊ฒŒ ๋‹ค์ ธ๋ด…์‹œ๋‹ค."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

Zustand๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ํ•˜๋Š” ์‹ค์ˆ˜๋Š” 'ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ์ฐฝ๊ณ '๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Redux์˜ Store ํ•˜๋‚˜์งœ๋ฆฌ ์ฒ ํ•™๊ณผ ํ—ท๊ฐˆ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Zustand ์Šคํ† ์–ด ์•ˆ์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜(set)๋Š” ๊ธฐ์กด ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ๊ฐ์ฒด(์ฐธ์กฐ)๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ๋ฆฌ์•กํŠธ ํŠธ๋ฆฌ์— ๋ณ€๊ฒฝ์„ ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ† ์–ด๊ฐ€ ๋„ˆ๋ฌด ๊ฑฐ๋Œ€ํ•˜๊ณ  ์ค‘์ฒฉ(Nest)์ด ๊นŠ์–ด์ง€๋ฉด, ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž(...) ์ง€์˜ฅ์ด ์—ด๋ฆฌ๊ณ  ํœด๋จผ ์—๋Ÿฌ๋กœ ์ฐธ์กฐ ๋™์ผ์„ฑ(Reference Equality) ํ•จ์ •์— ๋น ์ง€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

'์–ด๋–ป๊ฒŒ ์Šคํ† ์–ด๋ฅผ ์ƒ์„ฑ(create)ํ•˜๊ณ , ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ (get), ์•ˆ์ „ํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธํ•  ๊ฒƒ์ธ๊ฐ€(set)'๋ฅผ ๊นŠ์ด ์ดํ•ดํ•ด์•ผ๋งŒ ๊นƒํ„ธ์ฒ˜๋Ÿผ ๊ฐ€๋ฒผ์šด Zustand์˜ ์ง„์งœ ์†๋„๋ฅผ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ—๏ธ 1. ์Šคํ† ์–ด์˜ ํƒ„์ƒ: create

Zustand ์Šคํ† ์–ด๋Š” create ํ•จ์ˆ˜ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. create๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋ฐ, ์ด ์ฝœ๋ฐฑ์€ set, get, api๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ๊ฐ์ฒด(์ดˆ๊ธฐ ์ƒํƒœ์™€ ์•ก์…˜)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

// ๐Ÿฃ ์˜์ฒ : Zustand์—์„œ๋Š” Reducer๊ฐ€ ๋”ฐ๋กœ ์—†์œผ๋‹ˆ, ์•ก์…˜ ํ•จ์ˆ˜๋„ ๋ฐ”๋กœ ๋„ฃ์œผ๋ฉด ๋˜๋„ค์š”!
import { create } from 'zustand';
 
interface EditorState {
  title: string;
  content: string;
  wordCount: number;
  setTitle: (title: string) => void;
  setContent: (content: string) => void;
}
 
export const useEditorStore = create<EditorState>()((set, get) => ({
  title: '',
  content: '',
  wordCount: 0,
  
  setTitle: (title) => set({ title }), // ๐Ÿ’ก ์–•์€ ๋ณ‘ํ•ฉ!
  setContent: (content) => {
    // ๐Ÿ’ก get()์œผ๋กœ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์–ด์š”!
    const currentWordCount = content.trim().split(/\s+/).length;
    set({ content, wordCount: currentWordCount });
  },
}));

๐Ÿ’ก create๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ์ปค๋ง(Currying) ํŒจํ„ด

์œ„ TypeScript ์˜ˆ์ œ์—์„œ <EditorState>()(...) ์ฒ˜๋Ÿผ ๊ด„ํ˜ธ๊ฐ€ ์—ฐ์†๋˜๋Š” ํŒจํ„ด์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Zustand๊ฐ€ ํƒ€์ž… ์ถ”๋ก ์„ ์™„๋ฒฝํ•˜๊ฒŒ ๋•๊ธฐ ์œ„ํ•ด ๋นˆ ์ธ์ž๋กœ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•˜๊ณ , ๊ทธ๋‹ค์Œ ์ง„์งœ ์Šคํ† ์–ด ์ •์˜๋ฅผ ๋ฐ›๋Š” ์ปค๋ง(Currying) ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. (TS๋ฅผ ์“ธ ๋•Œ๋งŒ ๋“ฑ์žฅํ•˜๋Š” ๊ดด์ƒํ•œ ๊ด„ํ˜ธ์˜ ์ •์ฒด์ž…๋‹ˆ๋‹ค.)


๐ŸŽฏ 2. ์—…๋ฐ์ดํŠธ์˜ ํ•ต: set๊ณผ ์–•์€ ๋ณ‘ํ•ฉ (Shallow Merge)

set ํ•จ์ˆ˜๋Š” Zustand์˜ ์•ŒํŒŒ์ด์ž ์˜ค๋ฉ”๊ฐ€์ž…๋‹ˆ๋‹ค.

React์˜ useState์—์„œ ๋ฐฐ์—ด ํ›…(setState)์„ ์‚ฌ์šฉํ•  ๋•Œ 1์ฐจ์›(Root ๋ ˆ๋ฒจ) ์ƒํƒœ ํ•„๋“œ๋“ค์€ ์–ด๋–ค๊ฐ€์š”? ๊ธฐ์กด ์ƒํƒœ๋ฅผ ๋‹ค ๋ณต์‚ฌ(...prev)ํ•ด์„œ ๋„ฃ์–ด์ค˜์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ Zustand์˜ set์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ตœ์ƒ์œ„(1st level) ์†์„ฑ๋“ค์— ๋Œ€ํ•ด ์–•์€ ๋ณ‘ํ•ฉ(Shallow Merge) ์„ ์•Œ์•„์„œ ํ•ด์ค๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: Zustand๋Š” ๋˜‘๋˜‘ํ•ด์š”. ๋ช…์‹œํ•œ ํ•„๋“œ๋งŒ ๋ฎ์–ด์“ฐ๊ณ  ๋‚˜๋จธ์ง€๋Š” ๊ฑด๋“ค์ง€ ์•Š์•„์š”.
const useUserStore = create((set) => ({
  name: '์˜์ฒ ',
  level: 1,
  
  // โ›” useState ๋ฐฉ์‹ (๋ถˆํ•„์š”ํ•œ ์ค‘๋ณต)
  levelUpBad: () => set((state) => ({ ...state, level: state.level + 1 })),
  
  // โœ… Zustand ๋ฐฉ์‹ (์ž๋™ ์–•์€ ๋ณ‘ํ•ฉ)
  levelUpGood: () => set((state) => ({ level: state.level + 1 })),
}));

๐Ÿšจ ๋ถˆ๋ณ€์„ฑ์˜ ํ•จ์ •: ์ค‘์ฒฉ๋œ ๊ฐ์ฒด(Nested Objects)

์–•์€ ๋ณ‘ํ•ฉ์€ ์ตœ์ƒ์œ„ ๋ށ์Šค(Depth 1)์—์„œ๋งŒ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ๋œ ์†์„ฑ์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜๋™์œผ๋กœ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ˆ ๊ทธ๋Ÿฌ๋ฉด ์ฐธ์กฐ๊ฐ€ ๋Š๊ฒจ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

// ๐Ÿ˜ก ์˜์ˆ˜: "์˜์ฒ  ๋‹˜! ํ”„๋กœํ•„ ์‚ฌ์ง„ ๋ฐ”๊ฟจ๋Š”๋ฐ ์™œ ํ—ค๋” ์ด๋ฏธ์ง€๋Š” ์•ˆ ๋ฐ”๋€Œ์–ด์š”?!"
 
const useDeepStore = create((set) => ({
  user: {
    name: '์˜์ฒ ',
    profile: { url: 'old.jpg', badge: 'junior' }
  },
  
  // โŒ ๋”์ฐํ•œ ์‹ค์ˆ˜ (์ฐธ์กฐ ๋™์ผ์„ฑ ๊นจ์ง, ๋ถˆ๋ณ€์„ฑ ์œ„๋ฐ˜)
  updateProfileBad: (newUrl) => set((state) => {
    state.user.profile.url = newUrl; // Mutation! ๋ฆฌ์•กํŠธ๊ฐ€ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ ๋ชปํ•จ
    return { user: state.user }; 
  }),
 
  // โœ… ์•ˆ์ „ํ•œ ๋ถˆ๋ณ€์„ฑ ์—…๋ฐ์ดํŠธ (์Šคํ”„๋ ˆ๋“œ ์ง€์˜ฅ)
  updateProfileSpread: (newUrl) => set((state) => ({
    user: {
      ...state.user,
      profile: {
        ...state.user.profile,
        url: newUrl
      }
    }
  }))
}));

๐Ÿฆ ์˜ํ˜ธ์˜ ํ•œ๋งˆ๋””: "์ด๋ž˜์„œ ์Šคํ† ์–ด๋ฅผ ๋ชจ๋†€๋ฆฌ์‹ํ•˜๊ฒŒ ์งœ๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๋ฐ•์‚ด ๋‚œ๋‹ค๋Š” ๊ฒ๋‹ˆ๋‹ค. ๊นŠ์ด๊ฐ€ 2๋ށ์Šค ์ด์ƒ ๋“ค์–ด๊ฐ€๋ฉด Immer ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์“ฐ๊ฑฐ๋‚˜, ์Šคํ† ์–ด ์ž์ฒด๋ฅผ ๋‚ฉ์ž‘(Flat)ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜์„ธ์š”."


๐Ÿ” 3. ํ˜„์žฌ ์ƒํƒœ๋ฅผ ํ›”์ณ๋ณด๋Š” get

์•ก์…˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ƒํƒœ๋ฅผ ์ฝ์–ด์•ผ ํ•  ๋•Œ๋‚˜, ์ด์ „ ์ƒํƒœ ๊ฐ’์„ ๊ณ„์‚ฐ์— ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ๋Š” get()์„ ๊บผ๋‚ด ์”๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋น„๋™๊ธฐ ํ•จ์ˆ˜(API ํ˜ธ์ถœ ๋“ฑ) ๋’ค์— ์ตœ์‹  ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด get()์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.

const useCounterStore = create((set, get) => ({
  count: 0,
  submitScore: async () => {
    const currentCount = get().count; // ๐Ÿ’ก ๋น„๋™๊ธฐ ์ž‘์—… ์ง์ „ ์Šค๋ƒ…์ƒท ์ฝ๊ธฐ
    await api.post('/score', { score: currentCount });
    
    // ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ๋‹ค์‹œ get()์„ ํ•˜๋ฉด API ๋Œ€๊ธฐ ์ค‘ ๋ณ€ํ•œ ์ตœ์‹  ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Œ.
  }
}));

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. Zustand์˜ set ํ•จ์ˆ˜๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋ฐฉ์‹์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • A) ๋ฌด์กฐ๊ฑด ์ „์ฒด ์ƒํƒœ๋ฅผ ์ƒˆ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•œ๋‹ค.
  • B) ๊นŠ์€ ๋ถˆ๋ณ€์„ฑ(Deep Immutability) ๋ณด์žฅ
  • C) ์ตœ์ƒ์œ„ ๋ށ์Šค(Depth 1)์— ๋Œ€ํ•œ ์–•์€ ๋ณ‘ํ•ฉ (Shallow Merge)
  • D) React์˜ useState ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ ๋ฐฉ์‹๊ณผ ์™„์ „ ๋™์ผ

โœ… ์ •๋‹ต: C

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: Zustand์˜ set์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๊ธฐ์กด ์ƒํƒœ ์ตœ์ƒ์œ„(1st level) ํ•„๋“œ๋“ค์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ ์–•์€ ๋ณ‘ํ•ฉ์„ ํ•ด์ค๋‹ˆ๋‹ค. ๋•๋ถ„์— ...state ๊ฐ™์€ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋ฅผ ๋งค๋ฒˆ ์ ์„ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, Zustand๊ฐ€ ๋งˆ๋ฒ•์‚ฌ๋Š” ์•„๋‹ˆ์—์š”. ์ค‘์ฒฉ ๊ฐ์ฒด ๊นŠ์€ ๊ณณ๊นŒ์ง€ ์•Œ์•„์„œ ๋ณ‘ํ•ฉํ•ด์ฃผ์ง€ ์•Š์œผ๋‹ˆ 2๋ށ์Šค๋ถ€ํ„ฐ๋Š” ์กฐ์‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "Zustand์˜ set์€ ๊ฒ‰๋„๋Š” 1์ฐจ์›๋งŒ ์•Œ์•„์„œ ๋ณ‘ํ•ฉํ•ด์ฃผ๋Š” ์นœ์ ˆํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค."

Q2. ๋น„๋™๊ธฐ ํ†ต์‹ (API ํ˜ธ์ถœ) ์ค‘์— ์ตœ์‹  ์ƒํƒœ๋ฅผ ์ฝ์–ด์™€์•ผ ํ•  ๋•Œ ๊ฐ€์žฅ ์˜ฌ๋ฐ”๋ฅธ Zustand ์‚ฌ์šฉ๋ฒ•์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • A) ์Šคํ† ์–ด ์™ธ๋ถ€์— ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฐธ์กฐํ•œ๋‹ค.
  • B) ์ฝœ๋ฐฑ์œผ๋กœ ์ฃผ์ž…๋˜๋Š” get ํ•จ์ˆ˜(get())๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ˜„์žฌ ์Šค๋ƒ…์ƒท์„ ์ฐ์–ด์˜จ๋‹ค.
  • C) React์˜ useRef๋ฅผ ๋นŒ๋ ค์„œ ์Šคํ† ์–ด์— ์—ฐ๊ฒฐํ•ด๋‘”๋‹ค.
  • D) set ํ•จ์ˆ˜๋ฅผ ๊ฐ•์ œ๋กœ ํ˜ธ์ถœํ•ด์„œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐœ์ƒ์‹œํ‚จ ๋’ค ์ƒํƒœ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ์Šคํ† ์–ด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ create((set, get) => ...) ํ˜•ํƒœ๋กœ get์ด ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์•ก์…˜ ํ•จ์ˆ˜๋‚˜ ๋น„๋™๊ธฐ ๋กœ์ง ์ค‘๊ฐ„์— ํ˜„์žฌ ์ƒํƒœ๊ฐ’์„ ์ฝ์–ด์•ผ ํ•  ๋•Œ๋Š” get()์„ ํ˜ธ์ถœํ•˜๋ฉด ์ฆ‰์‹œ ์ตœ์‹  ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, ์ „์—ญ ์ƒํƒœ๋ฅผ ์“ธ ๋•Œ๋Š” ์ฒ ์ €ํ•˜๊ฒŒ ์ œ๊ณต๋œ ๋„๊ตฌ(get)๋งŒ ํ™œ์šฉํ•ด์•ผ์ง€ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋‚˜ React ํ›…(useRef)์— ์˜์กดํ•˜๋ฉด ์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "๊ฐ’์ด ๊ถ๊ธˆํ•˜๋ฉด ํ›”์ณ๋ณด๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹น๋‹นํ•˜๊ฒŒ get()์„ ์š”์ฒญํ•˜์„ธ์š”."

Q3. ๐Ÿ‹๏ธโ€โ™‚๏ธ ์˜์ฒ ์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„ (Q&A)

์˜์ฒ ์ด๊ฐ€ ์‡ผํ•‘๋ชฐ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๋ฉด์„œ cart ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ํŠน์ • ์•„์ดํ…œ์˜ ์ˆ˜๋Ÿ‰(quantity)๋งŒ ์ฆ๊ฐ€์‹œํ‚ค๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ† ์–ด ์ƒํƒœ ๊ตฌ์กฐ๋Š” { cart: [{ id: 1, qty: 1 }] } ์ž…๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ set์„ ํ˜ธ์ถœํ•ด์•ผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฆฌ์•กํŠธ ํ™”๋ฉด์— ๋ฐ˜์˜๋ ๊นŒ์š”?

โœ… ์ •๋‹ต: map ๋ฉ”์„œ๋“œ ๋“ฑ์„ ์ด์šฉํ•ด ์ˆ˜์ •๋˜๋Š” ์•„์ดํ…œ์˜ ์ƒˆ๋กœ์šด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ค์–ด ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ cart ๋ฐฐ์—ด ์ „์ฒด๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: Zustand ์ตœ์ƒ์œ„์˜ cart ํ‚ค ์ž์ฒด๋Š” ์–•์€ ๋ณ‘ํ•ฉ์„ ์ง€์›ํ•˜์ง€๋งŒ, ๊ทธ ๋‚ด๋ถ€ ๋ฐฐ์—ด์˜ ์š”์†Œ๊ฐ€ ๊ฐ€์ง„ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ˆ˜์ •(item.qty++)ํ•˜๋ฉด ์›๋ณธ ๊ฐ์ฒด๋ฅผ ๋ณ€์ด(Mutation)์‹œํ‚ค๋Š” ๊ผด์ด ๋ฉ๋‹ˆ๋‹ค. ์–•์€ ๋น„๊ต(!==)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” Zustand์™€ React๋Š” ๊ฐ์ฒด์˜ ๋‚ด์žฅ ์ฃผ์†Œ๊ฐ’์ด ๋˜‘๊ฐ™์œผ๋‹ˆ ํ™”๋ฉด์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, item.qty = newValue ์ฒ˜๋Ÿผ ์ฐŒ๋ฅด๋Š” ๋ฐฉ์‹์€ ๋ฐฐ์—ด ์•ˆ์— ์ง€๋ขฐ๋ฅผ ์‹ฌ๋Š” ํ–‰์œ„์˜ˆ์š”. ๋ฐ˜๋“œ์‹œ ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋‚˜ ๋ถˆ๋ณ€์„ฑ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜(Immer ๋“ฑ)๋ฅผ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "Zustand์˜ set์€ ํŽธํŒ(1์ฐจ์›)์—๋งŒ ์ž๋™ ๋ณ‘ํ•ฉ ๋งˆ๋ฒ•์„ ๋ถ€๋ ค์ค๋‹ˆ๋‹ค. ์„œ๋ž ์•ˆ์˜ ๋ณด์„ํ•จ ๋‚ด์šฉ๋ฌผ์„ ๋ฐ”๊ฟ€ ๋•Œ๋Š” ๋ณด์„ํ•จ ๋ชจ์–‘ ์ „์ฒด๋ฅผ ์ƒˆ๋กœ ์งœ์„œ ๊ต์ฒดํ•˜์„ธ์š”."

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜๋„ ์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜ํ•œํ…Œ ๊นŠ์€ ๋ณต์‚ฌ ์‹ค์ˆ˜๋กœ ํ˜ผ๋‚ฌ๋‹ค. ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๊ฐ€ ์•ˆ ๋ฐ”๋€Œ์–ด์„œ ๋ฐฑ์—”๋“œ ์บ์‹œ ๋ฌธ์ œ์ธ ์ค„ ์•Œ๊ณ  ์˜์ˆ˜ ๋‹˜ํ•œํ…Œ ๋”ฐ์ง€๋Ÿฌ ๊ฐˆ ๋ป”ํ–ˆ๋Š”๋ฐ, ๋‚ด Zustand ๋กœ์ง์ด Mutations ๋ฒ”๋ฒ…์ด์—ˆ๋‹ค๋‹ˆ ์‹์€๋•€์ด ์ซ™ ๋‚ฌ๋‹ค. state.user.profile.url = '...' ์ด๊ฑฐ ๋‚ด๊ฐ€ Vanilla JS ํ•˜๋˜ ๋ฒ„๋ฆ‡์ด ์•„์ง๋„ ๋‚จ์•„์žˆ์—ˆ๋„ค ใ… ใ…  ๋‚ด์ผ์€ ์ด ๊นŠ์€ ๋ށ์Šค๋ฅผ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋‚˜ ๋„๋ฉ”์ธ ๋‹จ์œ„๋กœ ํ‰ํƒ„ํ™”(Flat)ํ•˜๋Š” ๋ฒ•์„ ์ œ๋Œ€๋กœ ์—ฌ์ญค๋ด์•ผ๊ฒ ๋‹ค. ์ง‘ ๊ฐ€์„œ ์”ป๊ณ  ์œ ํŠœ๋ธŒ๋กœ Zustand ๋ถˆ๋ณ€์„ฑ ๊ฐ•์˜ ํ•˜๋‚˜๋งŒ ๋” ๋ณด๊ณ  ์ž์•ผ์ง€. ํŒŒ์ดํŒ… ์˜์ฒ !

๐Ÿ’ก "์ƒํƒœ๋ฅผ ๊นŠ์ˆ™์ด ํŒŒ๊ณ ๋“ค์ˆ˜๋ก ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž์˜ ์ €์ฃผ๊ฐ€ ์‹œ์ž‘๋œ๋‹ค. ๋‚ฉ์ž‘(Flat)ํ•œ ์Šคํ† ์–ด๊ฐ€ ์ƒ๋ช… ์—ฐ์žฅ์˜ ๊ฟˆ!"