๐Ÿ• 03. ์Šฌ๋ผ์ด์Šค ํŒจํ„ด (Slice Pattern): ์Šคํ† ์–ด๋ฅผ ์กฐ๋ฆฝ์‹์œผ๋กœ ์ชผ๊ฐœ๊ธฐ

๐Ÿ“‹ ๊ฐœ์š”

๊ฑฐ๋Œ€ํ•ด์ง„ Zustand ์Šคํ† ์–ด๋ฅผ ๊ธฐ๋Šฅ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์กฐ๋ฆฝํ•˜๋Š” ๋งˆ์ดํฌ๋กœ ์•„ํ‚คํ…์ฒ˜

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

  • ๋น„๋Œ€ํ•ด์ง„ ์Šคํ† ์–ด๋ฅผ ๊ด€์‹ฌ์‚ฌ(๋„๋ฉ”์ธ)๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ์กฐ๊ฐ(Slice) ํŒจํ„ด์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ Slice๋ฅผ ํ•˜๋‚˜๋กœ ๊ฒฐํ•ฉํ•˜๊ณ , Slice ๊ฐ„์— ์ƒํƒœ๋ฅผ ๊ต์ฐจ ์ฐธ์กฐ(ํ†ต์‹ )ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•œ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


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

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

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
์Šคํ† ์–ด ๋น„๋Œ€ํ™” ๋ฌธ์ œ์  โ†’ Slice ๋ถ„๋ฆฌ ๊ธฐ๋ฒ• โ†’ ์ค‘์•™ ํ†ตํ•ฉ ์Šคํ† ์–ด(BoundStore) ๊ฒฐํ•ฉ โ†’ Slice ๊ฐ„ ํ†ต์‹ 

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

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜, ์–ด์ œ ๋ง์”€ํ•˜์‹  ๋Œ€๋กœ ์Šคํ† ์–ด ๋ށ์Šค๋ฅผ ๊นŠ๊ฒŒ ์•ˆ ํŒŒ๋ ค๊ณ  ๋…ธ๋ ฅ ์ค‘์ธ๋ฐ์š”. ๊ทธ๋Ÿฌ๋‹ค ๋ณด๋‹ˆ๊นŒ ์ „์ฒด ์ƒํƒœ๋ฅผ ๋“ค๊ณ  ์žˆ๋Š” useAppStore.ts ํŒŒ์ผ์ด 500์ค„์ด ๋„˜์–ด๊ฐ”์–ด์š”! ๋กœ์ง ์ฐพ๊ธฐ๋„ ํž˜๋“ค๊ณ  ๋„ˆ๋ฌด ๋šฑ๋šฑํ•œ๋ฐ ์ด๊ฑฐ ํŒŒ์ผ ๋‹จ์œ„๋กœ ๋‹ค ๋ถ„๋ฆฌํ•ด์•ผ ํ• ๊นŒ์š”?"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, ์Šคํ† ์–ด๊ฐ€ ๋น„๋Œ€ํ•ด์ง€๋Š” ํ˜„์ƒ์„ ๊ฒช๊ณ  ๊ณ„์‹œ๋Š”๊ตฐ์š”. Zustand๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์Šคํ† ์–ด๋ฅผ ๋งŒ๋“ค์–ด๋„ ๋˜์ง€๋งŒ, ์—ฐ๊ด€๋œ ์ƒํƒœ๋ผ๋ฆฌ ์—ฎ์ด๋Š” ๊ตฌ์กฐ๋ผ๋ฉด ํ•˜๋‚˜์˜ ํฐ ์Šคํ† ์–ด๋ฅผ ์œ ์ง€ํ•˜๋˜ ๋‚ด๋ถ€๋ฅผ ์กฐ๋ฆฝ์‹ ๋ธ”๋ก์ฒ˜๋Ÿผ ์ชผ๊ฐœ์„œ ํ•ฉ์น˜๋Š” '์Šฌ๋ผ์ด์Šค ํŒจํ„ด(Slice Pattern)'์„ ์ ์šฉํ•ด์•ผ ์œ ์ง€๋ณด์ˆ˜๋„ ์žก๊ณ  ์ƒํƒœ ๊ฐ„ ํ†ต์‹ ๋„ ํŽธํ•ด์ง‘๋‹ˆ๋‹ค. ๋ ˆ๊ณ  ์กฐ๋ฆฝ๋ฒ•์„ ๋ฐฐ์›Œ๋ด…์‹œ๋‹ค."

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

Zustand๋กœ ์•ฑ์„ ๊ตฌ์ถ•ํ•˜๋‹ค ๋ณด๋ฉด, ์ „์—ญ ์ƒํƒœ๋Š” ํ•„์—ฐ์ ์œผ๋กœ ๋น„๋Œ€ํ•ด์ง‘๋‹ˆ๋‹ค. ์ธ์ฆ/์ธ๊ฐ€๋ฅผ ๋‹ด๋‹นํ•˜๋Š” User ๋„๋ฉ”์ธ, ๋‹คํฌ ๋ชจ๋“œ/์‚ฌ์ด๋“œ๋ฐ” ์—ฌ๋ถ€๋ฅผ ๊ธฐ์–ตํ•˜๋Š” UI ๋„๋ฉ”์ธ, ๊ทธ๋ฆฌ๊ณ  ์œ ์ €๊ฐ€ ์ž‘์„ฑ ์ค‘์ด๋˜ ์ž„์‹œ ๊ฒŒ์‹œํŒ ํผ ๋ฐ์ดํ„ฐ ๋“ฑ ์—ญํ• ์ด ์ „ํ˜€ ๋‹ค๋ฅธ ์ƒํƒœ๋“ค์ด ํ•œ ํŒŒ์ผ์— ํ˜ผ์žฌํ•˜๊ฒŒ ๋˜๋ฉด ์œ ์ง€๋ณด์ˆ˜์„ฑ์€ ๋š ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.

Redux์—์„œ๋Š” ๋ณดํ†ต combineReducers๋ฅผ ์‚ฌ์šฉํ•ด ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Zustand์—์„œ๋Š” ์ด์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ํ›จ์”ฌ ์ง๊ด€์ ์ธ Slice(์กฐ๊ฐ) ํŒจํ„ด์„ ๊ณต์‹์œผ๋กœ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

๊ฐ ๊ธฐ๋Šฅ๋ณ„ ์กฐ๊ฐ(Slice)์„ ๋ณ„๋„์˜ ํŒŒ์ผ์ด๋‚˜ ํ•จ์ˆ˜๋กœ ๋…๋ฆฝ์‹œํ‚ค๊ณ , ๋ฉ”์ธ ์Šคํ† ์–ด(useBoundStore)์—์„œ ๊ทธ ์กฐ๊ฐ๋“ค์„ ๊ฒฐํ•ฉ(Merge)ํ•˜์—ฌ ๋‹จ์ผ ์ฐฝ๊ตฌ(Single Source)๋ฅผ ์ œ๊ณตํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค.


๐Ÿ—๏ธ 1. ์Šคํ† ์–ด๋ฅผ ์กฐ๊ฐ๋‚ด๊ธฐ: Slice ์ƒ์„ฑ

๋จผ์ € ๋ชจ๋“  ๊ฒƒ์„ ๋“ค๊ณ  ์žˆ๋˜ ๋šฑ๋šฑํ•œ ์Šคํ† ์–ด๋ฅผ ๊ธฐ๋Šฅ(๋„๋ฉ”์ธ)๋ณ„ ์กฐ๊ฐ์œผ๋กœ ๋ถ„๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

A. ์ผ๋ฐ˜ ์Šคํ† ์–ด(์ „ํ†ต ๋ฐฉ์‹)์˜ ๋ฌธ์ œ

// ๐Ÿฃ ์˜์ฒ : ํŒŒ์ผ ํ•˜๋‚˜์— ๋‹ค ๋•Œ๋ ค๋ฐ•์•˜๋”๋‹ˆ ์ฝ”๋“œ๊ฐ€ 500์ค„์ด์—์š”...
const useStore = create((set) => ({
  user: null, // ์œ ์ € ๊ธฐ๋Šฅ
  login: () => { ... },
  
  isDarkMode: false, // UI ๊ธฐ๋Šฅ
  toggleTheme: () => { ... },
  
  cartItems: [], // ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ธฐ๋Šฅ
  addItem: () => { ... },
}));

B. Slice ์ชผ๊ฐœ๊ธฐ (๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ)

๊ฐ Slice๋Š” Zustand์˜ StateCreator ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ๋…๋ฆฝ์ ์œผ๋กœ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์œ ์ € ๋กœ์ง๊ณผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋กœ์ง์ด ์„œ๋กœ์˜ ์‹œ์•ผ์—์„œ ๋ถ„๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

// features/user/userSlice.ts
import { StateCreator } from 'zustand';
 
export interface UserSlice {
  user: string | null;
  login: (name: string) => void;
  logout: () => void;
}
 
// ๐Ÿฆ ์˜ํ˜ธ: ์ด Slice๋Š” ์ž๊ธฐ๊ฐ€ User ๊ด€๋ จ๋œ ์ผ๋งŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ•ด์š”.
export const createUserSlice: StateCreator<UserSlice> = (set) => ({
  user: null,
  login: (name) => set({ user: name }),
  logout: () => set({ user: null }),
});
// features/cart/cartSlice.ts
import { StateCreator } from 'zustand';
 
export interface CartSlice {
  cartItems: string[];
  addItem: (item: string) => void;
}
 
export const createCartSlice: StateCreator<CartSlice> = (set) => ({
  cartItems: [],
  addItem: (item) => set((state) => ({ cartItems: [...state.cartItems, item] })),
});

๐Ÿงฉ 2. ๋ฉ”์ธ ์Šคํ† ์–ด์—์„œ ์กฐ๋ฆฝ(Combine)ํ•˜๊ธฐ

์ž, ํฉ์–ด์ ธ ์žˆ๋Š” ์กฐ๊ฐ๋“ค์„ ๋ฉ”์ธ ์Šคํ† ์–ด์—์„œ ํ•˜๋‚˜๋กœ ๋ญ‰์ณ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์ธ ์Šคํ† ์–ด๋ฅผ ๋ณดํ†ต Bound Store(๋ฌถ์ธ ์Šคํ† ์–ด)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž(...)๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ฐ์˜ Slice ์ƒ์„ฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ƒํƒœ ํƒ€์ž…(์ธํ„ฐํŽ˜์ด์Šค)๋„ ํ•˜๋‚˜๋กœ ํ•ฉ์นฉ๋‹ˆ๋‹ค(Intersection Type).

// store/useBoundStore.ts
import { create } from 'zustand';
import { UserSlice, createUserSlice } from '../features/user/userSlice';
import { CartSlice, createCartSlice } from '../features/cart/cartSlice';
 
// ๐Ÿฃ ์˜์ฒ : ์—ฌ๊ธฐ์„œ ํƒ€์ž…๋“ค์„ '+' ๊ธฐํ˜ธ์ฒ˜๋Ÿผ(&) ํ•ฉ์น˜๋Š”๊ตฐ์š”!
type StoreState = UserSlice & CartSlice;
 
// ๐Ÿฆ ์˜ํ˜ธ: set, get, api๋ฅผ ๊ฐ๊ฐ์˜ Slice ํ•จ์ˆ˜์— ๊ทธ๋Œ€๋กœ ํ† ์Šค(Toss)ํ•ฉ๋‹ˆ๋‹ค.
export const useBoundStore = create<StoreState>()((...a) => ({
  ...createUserSlice(...a),
  ...createCartSlice(...a),
}));

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ์ž…์žฅ์—์„œ๋Š” ๋‹จ์ผ ์Šคํ† ์–ด(useBoundStore) ํ•˜๋‚˜๋งŒ ์ž„ํฌํŠธํ•˜๊ณ , ์œ ์ € ์ •๋ณด๋“  ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ •๋ณด๋“  ์™์™ ๋ฝ‘์•„(Select)๋‹ค ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


โšก 3. Slice ๊ฐ„์˜ ํ†ต์‹  (๊ต์ฐจ ์ฐธ์กฐ)

ํ•˜๋‚˜์˜ ํฐ ์Šคํ† ์–ด ๋‚ด์—์„œ Slice๋“ค๋ผ๋ฆฌ ์„œ๋กœ ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•ด์•ผ ํ•  ์ƒํ™ฉ์ด ์ƒ๊ธฐ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๊ทธ์•„์›ƒ์„ ํ•˜๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋„ ๊ฐ™์ด ์ดˆ๊ธฐํ™”๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”?

์ด๋•Œ Zustand์˜ ๊ฐ•๋ ฅํ•จ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. ๊ฐ ์กฐ๊ฐ(Slice)๋“ค์€ get() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ „์ฒด ์Šคํ† ์–ด(Bound Store)์˜ ์ƒํƒœ๋ฅผ ์ฝ๊ณ  ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { StateCreator } from 'zustand';
// ๐Ÿ’ก ๊ต์ฐจ ์ฐธ์กฐ๋ฅผ ์œ„ํ•ด ์ „์ฒด ์Šคํ† ์–ด ํƒ€์ž…์„ ์ œ๋„ค๋ฆญ์— ๋„ฃ์–ด์•ผ ํ•ด์š”.
import { StoreState } from '../../store/useBoundStore';
 
export const createUserSlice: StateCreator<
  StoreState,
  [], // middleware
  [],
  UserSlice
> = (set, get) => ({
  user: null,
  login: (name) => set({ user: name }),
  // ๐Ÿค” ๋กœ๊ทธ์•„์›ƒํ•˜๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋„ ๋น„์šฐ์ž!
  logout: () => {
    // ๐Ÿฆ ์˜ํ˜ธ: ํ˜„์žฌ ์Šคํ† ์–ด ๊ตฌ์กฐ์ƒ Cart์˜ cartItems ํ•„๋“œ๋ฅผ ์ง์ ‘ ๋ฐ€์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ์–ด์š”.
    set({ user: null, cartItems: [] });
    // ๋งŒ์•ฝ CartSlice์˜ ๋น„์šฐ๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:
    // get().clearCart(); 
  },
});

๐ŸŒŸ ๋””์ž์ธ ์›์น™:
Slice ๊ฐ„ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋„ˆ๋ฌด ๋†’์•„์ง€๋ฉด ๋‹จ์ผ ๊ธฐ๋Šฅ์œผ๋กœ์„œ์˜ ๋…๋ฆฝ์„ฑ์ด ๋ฌด๋„ˆ์ง‘๋‹ˆ๋‹ค. ์œ ์ €๊ฐ€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ๋น„์šฐ๋Š” ์ •๋„๋Š” ๊ดœ์ฐฎ์ง€๋งŒ, ์„œ๋กœ์˜ ์ƒํƒœ๋ฅผ ๋ฏธ๋กœ์ฒ˜๋Ÿผ ์ฐธ์กฐํ•˜๊ฒŒ ์งœ์ง€ ๋งˆ์„ธ์š”! ๊ฐ€๊ธ‰์  ์ด๋ฒคํŠธ ์ค‘์‹ฌ ๋ถ„๋ฆฌ๊ฐ€ ์œ ์ง€๋ณด์ˆ˜์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


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

Q1. Zustand์—์„œ ๋น„๋Œ€ํ•ด์ง€๋Š” ๋ฉ”์ธ ์Šคํ† ์–ด๋ฅผ ๋ถ„๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํ”ํ•œ ํŒจํ„ด์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • A) ์Šฌ๋ผ์ด์Šค ํŒจํ„ด(Slice Pattern)
  • B) ์ปจํ…์ŠคํŠธ ๋ถ„๋ฆฌ ํŒจํ„ด(Context Split Pattern)
  • C) ๊ธ€๋กœ๋ฒŒ ์˜ต์ €๋ฒ„ ํŒจํ„ด(Global Observer Pattern)
  • D) ๋‹ค์ค‘ ์Šคํ† ์–ด ๊ฒฐํ•ฉ ํŒจํ„ด(Multiple Store Combine Pattern)

โœ… ์ •๋‹ต: A

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

  • ์›๋ฆฌ ์„ค๋ช…: ๋ฉ”์ธ ์Šคํ† ์–ด์˜ ๊ด€๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ์ปค์ง€๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๋„๋ฉ”์ธ๋ณ„ ๊ด€์‹ฌ์‚ฌ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์ด๋ฅผ ๋‹จ์ผ Bound Store์—์„œ ๊ฒฐํ•ฉ($merge)ํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜๋ฅผ ์Šฌ๋ผ์ด์Šค ํŒจํ„ด์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…๋ฆฝ์ ์ธ useStore๋ฅผ ๋ฌดํ•œ์ • ์ฐ์–ด๋‚ด๋Š” ๋ฐฉ์‹์€ ๊ต์ฐจ ์ฐธ์กฐ ํ†ต์‹ ์ด ์–ด๋ ค์›Œ์ง„๋‹ค๋Š” ๊ฑธ ์žŠ์œผ์‹œ๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "๊ฑฐ๋Œ€ํ•ด์ง„ ์Šคํ† ์–ด๋Š” ํ”ผ์ž ์กฐ๊ฐ ์ž๋ฅด๋“ฏ ๊ด€์‹ฌ์‚ฌ๋Œ€๋กœ ์Šฌ๋ผ์ด์Šค(Slice) ์ณ์„œ ๊ด€๋ฆฌํ•˜์„ธ์š”."

Q2. Slice ๊ฐ„์— ์„œ๋กœ์˜ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ(๊ต์ฐจ ์ฐธ์กฐ)ํ•ด์•ผ ํ•  ๋•Œ, Zustand ์Šฌ๋ผ์ด์Šค ๋‚ด์—์„œ ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ•˜๋‚˜์š”?

  • A) Redux์˜ dispatch๋ฅผ ์‚ฌ์šฉํ•ด ์•ก์…˜ ํ†ต์‹ ์„ ํ•œ๋‹ค.
  • B) ์Šฌ๋ผ์ด์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ์ฃผ์ž…๋ฐ›์€ get() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์ „์ฒด ์ƒํƒœ์— ์ ‘๊ทผํ•œ๋‹ค.
  • C) ๋‹ค๋ฅธ ์Šฌ๋ผ์ด์Šค ํŒŒ์ผ์„ ์ง์ ‘ importํ•ด์„œ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•œ๋‹ค.
  • D) ๊ต์ฐจ ์ฐธ์กฐ๋Š” ์ ˆ๋Œ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๊ณตํ†ต ๋ถ€๋ชจ ์Šฌ๋ผ์ด์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

โœ… ์ •๋‹ต: B

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

  • ์›๋ฆฌ ์„ค๋ช…: ์Šฌ๋ผ์ด์Šค ์ƒ์„ฑ ํ•จ์ˆ˜(StateCreator)๋Š” ๋ฌถ์—ฌ์ง„ ์ „์ฒด ์Šคํ† ์–ด(Bound Store)์˜ ํƒ€์ž… ์ปจํ…์ŠคํŠธ ์œ„์—์„œ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚ด๋ถ€์˜ get() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค๋ฅธ ์Šฌ๋ผ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ณ , set()์„ ํ†ตํ•ด ์ˆ˜์ •๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, ์Šฌ๋ผ์ด์Šค๋ฅผ ์กฐ๊ฐ๋ƒˆ๋‹ค๊ณ  ์„œ๋กœ ์†Œํ†ต์ด ๋Š๊ธฐ๋Š” ๊ฒŒ ์•„๋‹ˆ์—์š”. ํ†ฑ๋‹ˆ๋ฐ”ํ€ด๋“ค์€ get์ด๋ผ๋Š” ์ถ•์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "๋‹ค๋ฅธ ๋ถ€์„œ(Slice) ์„œ๋ฅ˜๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๊ฐ€์žฅ ๋น ๋ฅธ ๋ฌธ์€ get()์ž…๋‹ˆ๋‹ค."

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

์˜์ฒ ์ด๊ฐ€ ์‡ผํ•‘ ์•ฑ์˜ ์Šคํ† ์–ด๋ฅผ ๋งŒ๋“ค๋ฉด์„œ UI ์ƒํƒœ ๊ด€๋ฆฌ ์กฐ๊ฐ(UISlice)๊ณผ ๋‹คํฌ ๋ชจ๋“œ ํ† ๊ธ€ ํ•จ์ˆ˜, ๊ทธ๋ฆฌ๊ณ  User ๋„๋ฉ”์ธ์„ ๊ด€๋ฆฌ ์ค‘์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํ† ์–ด๋ฅผ ๋ถ„๋ฆฌ($useUIStore, $useUserStore)ํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ create ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ, ํŠน์ • ์ปดํฌ๋„ŒํŠธ์—์„œ ๋กœ๊ทธ์ธ ์ •๋ณด์™€ ๋‹คํฌ๋ชจ๋“œ ์ •๋ณด๋ฅผ ๋‘˜ ๋‹ค ์จ์•ผ ํ•œ๋‹ค๋ฉด ๊ฐ๊ฐ ๋”ฐ๋กœ ํ›…(hook)์„ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์Šฌ๋ผ์ด์Šค ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌถ์Œ ์Šคํ† ์–ด(useBoundStore)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์œ ์ง€๋ณด์ˆ˜ ์ง€์ ์ด ํŽธํ•ด์ง€๋‚˜์š”?

โœ… ์ •๋‹ต: ๋‹จ์ผ ์Šคํ† ์–ด๋กœ ๋ฌถ์–ด๋‘๋ฉด Slice ์ƒํƒœ ๊ฐ„์˜ ๊ต์ฐจ ์ ‘๊ทผ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ ๋กœ์ง ์ž‘์„ฑ์ด ํ•œ ๊ณณ์—์„œ ๊ฐ€๋Šฅํ•ด์ง€๋ฉฐ, ๋ Œ๋”๋ง ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋“ฑ ํ™•์žฅ์ด ์ˆ˜์›”ํ•ด์ง„๋‹ค.

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

  • ์›๋ฆฌ ์„ค๋ช…: ์—ฌ๋Ÿฌ ๊ฐœ์˜ create ์Šคํ† ์–ด๋ฅผ ๋งŒ๋“ค๋ฉด, "๋กœ๊ทธ์•„์›ƒ ์‹œ ๋‹คํฌ ๋ชจ๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค" ๊ฐ™์€ ๋กœ์ง์„ ์ปดํฌ๋„ŒํŠธ ๋‚ด์— useEffect๋กœ ๋•์ง€๋•์ง€ ๋ฌถ๊ฑฐ๋‚˜ ์Šคํ† ์–ด ์™ธ๋ถ€ ํŒŒ์ผ์—์„œ ๊ฐœ์ž…ํ•ด์•ผ ํ•˜๋Š” ๋”์ฐํ•œ ํŒŒํŽธํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆํ™”์˜ ์žฅ์ ์„ ๊ฑฐ๋‘๋˜, ๋ฐ์ดํ„ฐ๋ฅผ ์ง€๋ฐฐํ•˜๋Š” ์ค‘์•™ ์„ผํ„ฐ๋Š” BoundStore๋กœ ๋ฌถ์–ด์„œ ์ƒํƒœ ๊ฐ„์˜ ํ†ต์‹ ๊ณผ ๊ด€๋ฆฌ ํฌ์ธํŠธ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๋‚จ๊ฒจ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, ์Šคํ† ์–ด๋ฅผ ์กฐ๊ฐ๋ƒˆ๋‹ค๊ณ  ์™„์ „ํžˆ ๋‚จ๋‚จ์ด ๋œ ๊ฒŒ ์•„๋‹ˆ์—์š”. StateCreator๋ฅผ ์ด์šฉํ•ด ๋А์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉํ•ด์ฃผ๋ฉด, set๊ณผ get ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋™์ผ์„ ์ƒ์—์„œ ์‚ฌ์šฉํ•˜์—ฌ ์–ธ์ œ๋“  ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ๊ฑด๋“ค ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๐Ÿฆ ์˜ํ˜ธ: "์ž‘์€ ํ†ฑ๋‹ˆ๋ฐ”ํ€ด ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ๊ทธ์น˜๋ฉด ๊ฐ์ž ๋”ฐ๋กœ ๋†‰๋‹ˆ๋‹ค. ํ†ฑ๋‹ˆ๋ฅผ ๋‚˜๋ˆ  ๊นŽ๋”๋ผ๋„ ํ•˜๋‚˜์˜ ์‹œ๊ณ„ํŒ(Bound Store) ์œ„์— ์˜ฌ๋ ค์•ผ ์ •ํ™•ํ•œ ์‹œ๋„ˆ์ง€๋ฅผ ๋‚ด๋Š” ๋ฒ•์ด์ฃ ."

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

์™€. ์˜ค๋Š˜ useBoundStore.ts ๋งŒ๋“œ๋Š”๋ฐ, ๊ทธ๋™์•ˆ ์Šคํฌ๋กค ์••๋ฐ•์ด ์ฉ”์—ˆ๋˜ ์ฝ”๋“œ๊ฐ€ ๋งˆ๋ฒ•๊ฐ™์ด ๋ถ„๋ฆฌ๋˜์—ˆ๋‹ค! ์‹ฌ์ง€์–ด logout ํ•จ์ˆ˜์—์„œ cartItems๊นŒ์ง€ ์ง€์›Œ๋ฒ„๋ฆฌ๋‹ˆ๊นŒ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋“ค์ด ์Šคํฌํ† ์–ด ์•ˆ์—์„œ ์˜ˆ์˜๊ฒŒ ์†Œํ†ตํ•˜๋Š” ๊ธฐ๋ถ„์ด ๋“ค์—ˆ๋‹ค. ์—ญ์‹œ ์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜์ด ์งœ๋Š” ์•„ํ‚คํ…์ฒ˜๋Š” ๋ญ”๊ฐ€ ๋‹ฌ๋ผ๋„ ๋‹ค๋ฆ„! ๋‚ด์ผ์€ ํ‡ด๊ทผํ•˜๊ณ  ๋ชจ์ฒ˜๋Ÿผ ์น˜๋งฅ ํ•œ ์ž” ์‹œ์›ํ•˜๊ฒŒ ๊ฑธ์น˜๋ฉฐ, ์ƒˆ๋กœ ๋ฆฌํŒฉํ† ๋งํ•œ ์ฝ”๋“œ๋ฅผ ํ๋ญ‡ํ•˜๊ฒŒ ๊ฐ์ƒํ•ด๋ด์•ผ๊ฒ ๋‹ค ๐Ÿ—๐Ÿบ!

๐Ÿ’ก "์ƒํƒœ๋ฅผ ์กฐ๊ฐ(Slice)์ฒ˜๋Ÿผ ์ž˜๋ผ ๋‚˜๋ˆ„๊ณ , ๋ฉ”์ธ ์Šคํ† ์–ด๋ผ๋Š” ํ•˜๋‚˜์˜ ๋ ˆ๊ณ ํŒ์— ๋ผ์›Œ ๋งž์ถ”์ž."