[React] Zustand๋กœ ๋กœ๊ทธ์ธ ์ƒํƒœ ๊ด€๋ฆฌํ•˜๊ธฐ: ์ฝ”๋“œ + ๊ฐœ๋… ์„ค๋ช…

2025. 4. 10. 18:02ยท ๐™ต๐š›๐š˜๐š—๐š๐šŽ๐š—๐š/๐š๐šŽ๐šŠ๐šŒ๐š
๋ชฉ์ฐจ
  1. Zustand๋ž€ 
  2. Zustand ์„ค์น˜
  3. ์ „์ฒด ์ฝ”๋“œ
  4. ์ฝ”๋“œ ๋ถ„์„
  5. interface UserState
  6. create<UserState>()(...) & persist(...)
  7. setUser
  8. resetUser
  9. ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ 
๋ฐ˜์‘ํ˜•

 

์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ Zustand๋ฅผ ์ด์šฉํ•ด๋ณด์•˜๋‹ค. 

 

Introduction - Zustand

 

Introduction - Zustand

How to use Zustand

zustand.docs.pmnd.rs

pmndrs/zustand: ๐Ÿป React์—์„œ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ํ•„์ˆ˜ํ’ˆ

 

GitHub - pmndrs/zustand: ๐Ÿป Bear necessities for state management in React

๐Ÿป Bear necessities for state management in React. Contribute to pmndrs/zustand development by creating an account on GitHub.

github.com

 

์œ„ ์ฒซ๋ฒˆ์งธ ๋ฌธ์„œ๋กœ ๋“ค์–ด๊ฐ€๋ณด๋ฉด ๊ท€์—ฌ์šด ๊ณฐ๋Œ์ด๊ฐ€ ๋‚˜์˜ค๊ณ , one up ์„ ํด๋ฆญํ•˜๋ฉด ์ˆซ์ž๊ฐ€ ์˜ฌ๋ผ๊ฐ„๋‹ค.

zustand ์˜ˆ์ œ๋กœ ๋งŒ๋“ค์–ด ๋†“์€ ๊ฒƒ ๊ฐ™๋‹ค. 

 

 

Zustand๋ž€ 

๋…์ผ์–ด๋กœ '์ƒํƒœ'๋ผ๋Š” ๋œป์ด๊ณ , 

์ „์—ญ ์ƒํƒœ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. 

Redux๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ€๋ณ๊ณ  ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ(๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ํ‹€ ๊ฐ™์€ ์ฝ”๋“œ)๋„ ์ ๋‹ค.

 

Redux๋ฅผ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•ด๋ณธ ๊ฒฝํ—˜์€ ์—†์ง€๋งŒ, 

๊ฐ„๋‹จํžˆ ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ, Zustand ๋Œ€์‹  Redux๋ฅผ ์ผ๋‹ค๋ฉด ํŒŒ์ผ ์ˆ˜๋„ ๋Š˜๊ณ , ์ž‘์„ฑํ•ด์•ผํ•  ์ฝ”๋“œ๋Ÿ‰๋„ ๋” ๋งŽ์•˜์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์  ์ •๋„๋Š” ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค. 

 

 

Zustand ์„ค์น˜

Zustand๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

npm install zustand

 

 

 

์ „์ฒด ์ฝ”๋“œ

๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ ์ด ์ฝ”๋“œ๋Š” ์ด๋ ‡๊ฒŒ ๋˜๋ฉฐ, ๋ฐ‘์—์„œ ํ•˜๋‚˜ ํ•˜๋‚˜ ์ž์„ธํžˆ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

import {create} from "zustand";
import {persist} from "zustand/middleware";

interface UserState {
  token: string | null;
  expiresAt: number | null;
  user_id: string | null;
  nickname: string | null;
  email: string | null;
  provider: string | null;

  setUser: (user: Partial<Omit<UserState, 'setUser' | 'resetUser'>>) => void;
  resetUser: () => void;
}

export const useUserStore = create<UserState>()(
  persist(
    (set) => ({
      token: null,
      expiresAt: 0,
      user_id: null,
      nickname: null,
      email: null,
      provider: null,

      setUser: (user) =>
        set((state) => ({
          ...state,
          ...user,
        })),

      resetUser: () =>
        set({
          token: null,
          expiresAt: 0,
          user_id: null,
          nickname: null,
          email: null,
          provider: null,
        }),
    }),
    {
      name: "user-storage",
    }
  )
);

 

 

 

์ฝ”๋“œ ๋ถ„์„

interface UserState

interface UserState {
  token: string | null;
  expiresAt: number | null;
  user_id: string | null;
  nickname: string | null;
  email: string | null;
  provider: string | null;

  setUser: (user: Partial<Omit<UserState, 'setUser' | 'resetUser'>>) => void;
  resetUser: () => void;
}

 

UserState๋ผ๋Š” interface๋ฅผ ๋งŒ๋“ค์–ด์คฌ๋‹ค. 

์‚ฌ์šฉ์ž ๊ด€๋ จ ๊ฐ’๋“ค์„ ๋”ฐ๋กœ ๋‹ค๋ฃจ๋Š” ๊ฒƒ๋ณด๋‹ค ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ๋” ํšจ์œจ์ ์ด๋ผ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. 

๋ณ€์ˆ˜๋งŒ ์ •์˜ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜๋„ ๊ฐ™์ด ์ •์˜ํ–ˆ๋‹ค (setUser, resetUser) 

 

 

์ด์ œ ๊ฐ ์ฝ”๋“œ๋ฅผ ๋œฏ์–ด๋ณด์ž! 

  token: string | null;
  expiresAt: number | null;
  user_id: string | null;
  nickname: string | null;
  email: string | null;
  provider: string | null;

 

์ƒํƒœ ๊ด€๋ฆฌํ•  ๋•Œ ์“ฐ์ด๋Š” ์‚ฌ์šฉ์ž ์ƒํƒœ์˜ ํƒ€์ž…์„ ์ •์˜ํ•œ ๊ฒƒ์ด๋‹ค. 

string | null : string์ด๋‚˜ null์ด ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์ด๋ผ๋Š” ๋œป์ด๋‹ค.

 

 

 

setUser: (user: Partial<Omit<UserState, 'setUser' | 'resetUser'>>) => void;

โ‘  Omit<UserState, 'setUser' | 'resetUser'> : userState ํƒ€์ž…์—์„œ setUser๋ž‘ resetUser๋ฅผ ์ œ์™ธํ•จ(Omit)

 

Omit ์€ ์˜์–ด๋กœ ์ƒ๋žตํ•˜๋‹ค, ์ œ์™ธํ•˜๋‹ค ๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค. 

Omit<T, K>๋กœ ์‚ฌ์šฉ์„ ํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ํƒ€์ž… T์—์„œ ํ‚ค K๋ฅผ ์ œ์™ธํ•œ ํƒ€์ž…์„ ๋งŒ๋“œ๋Š” ๋„๊ตฌ์ด๋‹ค. 

์œ„์—์„œ T๋Š” UserState์ด๊ณ ,

K๋Š” 'setUser' | 'resetUser' ์ธ ๊ฒƒ์ด๋‹ค. 

 

์ด Omit์€ TypeScript์—๋งŒ ์žˆ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์ด๋‹ค. 

 

โ‘ก Partial<...>

T์˜ ๋ชจ๋“  ์†์„ฑ์„ ์„ ํƒ์ (optional)์œผ๋กœ ๋งŒ๋“ ๋‹ค.

์ฆ‰, ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์žˆ์–ด๋„ ๋˜๊ณ , ์ผ๋ถ€๋งŒ ์žˆ์–ด๋„ ๋œ๋‹ค๋Š” ๋œป์ด๋‹ค. 

 

useUserStore.getState().setUser({ nickname: "์‹ ์งฑ๊ตฌ" });

์–˜๋ฅผ ๋“ค์–ด ์œ„์™€ ๊ฐ™์€ ์‹์œผ๋กœ ์ „์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š” ์—†์ด ๋‹‰๋„ค์ž„๋งŒ(ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ) ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

create<UserState>()(...) & persist(...)

import {create} from "zustand";
import {persist} from "zustand/middleware";

export const useUserStore = create<UserState>()(
  persist(
    (set) => ({
      ...
    }),
    {
      name: "user-storage", // ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€ ํ‚ค ์ด๋ฆ„
    }
  )
);

 

์ผ๋‹จ create์™€ persist๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์„ธ import ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

create

create()๋Š” Zustnad์—์„œ store๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

์ „์—ญ ์ƒํƒœ๋ฅผ ์ •์˜ํ•˜๊ณ , ๊ทธ ์ƒํƒœ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. 

 

persist

persist() ๋Š” localstorage์— ์ƒํƒœ๋ฅผ ์ €์žฅํ•ด์ฃผ๋Š” ๋ฏธ๋“ค์›จ์–ด์ด๋‹ค. 

์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ ์œ ์ € ์ •๋ณด๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š”๋‹ค.

์ž๋™์œผ๋กœ localstorage.setItem('user-storage', ์ƒํƒœ) ์™€ ๊ฐ™์€ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. 

 

๋ฏธ๋“ค์›จ์–ด(Middleware)๋ž€?

๋‘ ๊ฐœ์˜ ๋ฌด์–ธ๊ฐ€ ์‚ฌ์ด์—์„œ ์ค‘๊ฐ„ ์—ญํ• ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งํ•œ๋‹ค. 

Zustand์—์„œ๋Š” ์Šคํ† ์–ด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฏธ๋“ค์›จ์–ด๋ผ๊ณ  ์ผ์ปซ๊ณ ,

persist ๋ฏธ๋“ค์›จ์–ด๋Š” ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ localStorage์— ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. 

 

 

 

setUser

setUser: (user) =>
  set((state) => ({
    ...state,
    ...user,
  })),

set()์€ Zustand์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜์ด๋‹ค. 

...state: ๊ธฐ์กด ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ.

...user: ์ƒˆ๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์œผ๋กœ ์ƒํƒœ๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ.

setUser({ userId: "userId123" }) ์œผ๋กœ ํ•œ๋‹ค๋ฉด userId๋งŒ ๋ณ€๊ฒฝ๋˜๊ณ , ๋‚˜๋จธ์ง€ ์ƒํƒœ ๊ฐ’๋“ค์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋œ๋‹ค.

 

 

 

resetUser

      resetUser: () =>
        set({
          token: null,
          refreshToken: null,
          expiresAt: 0,
          user_id: null,
          nickname: null,
          email: null,
          provider: null,
        }),

 

Zustand์˜ ์ƒํƒœ๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

์œ„ ๊ธ€๊ณผ ๊ฐ™์€ ์˜ˆ์ œ์—์„  ๋ณดํ†ต ๋กœ๊ทธ์•„์›ƒ์ด๋‚˜ ํƒˆํ‡ดํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 

๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ 

 

Login.tsx์—์„œ ์ €์žฅํ•œ user ์ •๋ณด๋ฅผ MyPage.tsx์—์„œ ๋ฐ‘๊ณผ ๊ฐ™์ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

const userId = useUserStore((state) => state.user_id); // ID ๊ฐ€์ ธ์˜ค๊ธฐ

 

๊ทธ๋Ÿฌ๋ฉด ์˜๋ฌธ์„ ์ œ๊ธฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ƒฅ localStorage.getItem์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ๋˜๋Š”๋ฐ, ์™œ ๊ตณ์ด ์ €๋ ‡๊ฒŒ ๊ฐ€์ ธ์˜ค๋Š”์ง€? 

 

์™œ๋ƒํ•˜๋ฉด localStorage.getItem์€ ์ž๋™ ๋ฆฌ๋ Œ๋”๋ง์ด ์•ˆ ๋˜์ง€๋งŒ, 

Zustand๋Š” ์ž๋™ ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ํ—ค๋”์— ๋‚ด ๋‹‰๋„ค์ž„(header.tsx)์ด ์žˆ๊ณ , ๋‚ด ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ชจ๋‹ฌ(MyPageModal.tsx)์—์„œ ๋‹‰๋„ค์ž„์„ ์ˆ˜์ •ํ–ˆ๋‹ค๊ณ  ์น˜์ž. 

์ˆ˜์ •ํ•จ๊ณผ ๋™์‹œ์— ํ—ค๋”์™€ ๋ชจ๋‹ฌ์— ์žˆ๋Š” ๋‹‰๋„ค์ž„์ด ๋™๊ธฐํ™”(๋ณ€๊ฒฝ)๋˜์–ด์•ผ ํ•œ๋‹ค.

 

Zustand๋ฅผ ์ด์šฉํ•˜๋ฉด ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ž๋งˆ์ž ์ƒํƒœ๋ฅผ ๊ตฌ๋… ์ค‘์ธ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ž๋™์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋‘ ์ฆ‰์‹œ ๋ณ€๊ฒฝ๋œ ๋‹‰๋„ค์ž„์„ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. 

๋ฐ˜๋ฉด, localStorage๋Š” ๋‹จ์ˆœํžˆ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์ด๊ณ , ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ React๋Š” ๊ทธ๊ฑธ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹‰๋„ค์ž„์„ ๋ฐ”๊พผ๋‹ค๋ฉด ๋ชจ๋‹ฌ์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ๋‹‰๋„ค์ž„์ด ๋ณด์ด์ง€๋งŒ, ํ—ค๋”์—๋Š” ์ด์ „ ๋‹‰๋„ค์ž„ ๊ทธ๋Œ€๋กœ์ผ ์ˆ˜ ์žˆ๋‹ค. 

 

 

์ถ”๊ฐ€์ ์œผ๋กœ ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์€ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

useUserStore.getState().setUser({
	nickname: response.data.nickname,
	email: response.data.email
});

 

 

 

๋ฐ˜์‘ํ˜•

'๐™ต๐š›๐š˜๐š—๐š๐šŽ๐š—๐š > ๐š๐šŽ๐šŠ๐šŒ๐š' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ๊ด€๋ฆฌ: package.json๊ณผ package-lock.json์„ ํ•จ๊ป˜ ์ปค๋ฐ‹ํ•ด์•ผ ํ•˜๋Š” ์ด์œ   (0) 2024.12.15
[REACT] ํŒŒ์ผ post application/octet-stream ์˜ค๋ฅ˜ ํ•ด๊ฒฐ: ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ๋ฐ์ดํ„ฐ ์ „์†ก ํŒ  (0) 2024.11.23
[REACT] Not Allowed to Load Local Resource ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ๋ฐ Apache HTTP Server ์„ค์ • ๋ฐฉ๋ฒ•  (0) 2024.11.22
  1. Zustand๋ž€ 
  2. Zustand ์„ค์น˜
  3. ์ „์ฒด ์ฝ”๋“œ
  4. ์ฝ”๋“œ ๋ถ„์„
  5. interface UserState
  6. create<UserState>()(...) & persist(...)
  7. setUser
  8. resetUser
  9. ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ 
'๐™ต๐š›๐š˜๐š—๐š๐šŽ๐š—๐š/๐š๐šŽ๐šŠ๐šŒ๐š' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ๊ด€๋ฆฌ: package.json๊ณผ package-lock.json์„ ํ•จ๊ป˜ ์ปค๋ฐ‹ํ•ด์•ผ ํ•˜๋Š” ์ด์œ 
  • [REACT] ํŒŒ์ผ post application/octet-stream ์˜ค๋ฅ˜ ํ•ด๊ฒฐ: ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ๋ฐ์ดํ„ฐ ์ „์†ก ํŒ
  • [REACT] Not Allowed to Load Local Resource ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ๋ฐ Apache HTTP Server ์„ค์ • ๋ฐฉ๋ฒ•
ํ•ด๋ฒ„๋‹ˆ
ํ•ด๋ฒ„๋‹ˆ
๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋ฐฐ์šด ๊ฒƒ๋“ค์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
ํ•ด๋ฒ„๋‹ˆ
DevNight
ํ•ด๋ฒ„๋‹ˆ
์ „์ฒด
์˜ค๋Š˜
์–ด์ œ
  • ์ „์ฒด๋ณด๊ธฐ (214) N
    • ๐š๐šŽ๐š๐š›๐š˜๐šœ๐š™๐šŽ๐šŒ๐š๐š’๐šŸ๐šŽ๐šœ (6)
      • ๐šƒ๐š’๐š™๐šœ (2)
      • ํšŒ๊ณ  (3)
      • ์‹ค์ˆ˜ ๋ชจ์Œ์ง‘ (0)
    • ๐™ฟ๐š›๐š˜๐š“๐šŽ๐šŒ๐š (3)
      • ๐™บ๐™พ๐š‚๐šƒ๐™ฐ ๐š†๐šŽ๐š‹ ๐™ฟ๐š›๐š˜๐š“๐šŽ๐šŒ๐š (2)
    • ๐™ฟ๐š›๐š˜๐š๐š›๐šŠ๐š–๐š–๐š’๐š—๐š ๐™ป๐šŠ๐š—๐š๐šž๐šŠ๐š๐šŽ (67)
      • ๐™ท๐šƒ๐™ผ๐™ป (6)
      • ๐™ฒ๐š‚๐š‚ (3)
      • ๐™น๐™ฐ๐š…๐™ฐ (47)
      • ๐™น๐šŠ๐šŸ๐šŠ๐š‚๐šŒ๐š›๐š’๐š™๐š (10)
      • ๐šƒ๐šข๐š™๐šŽ๐š‚๐šŒ๐š›๐š’๐š™๐š (1)
    • ๐™ฑ๐šŠ๐šŒ๐š”๐šŽ๐š—๐š (19)
      • ๐š‚๐š™๐š›๐š’๐š—๐š ๐™ฑ๐š˜๐š˜๐š (4)
      • ๐š‚๐š™๐š›๐š’๐š—๐š (3)
      • ํŒŒ์ผ ์ฒ˜๋ฆฌ (1)
      • ๐™น๐š‚๐™ฟ (6)
      • ๐š†๐™ด๐™ฑ (4)
    • ๐™ต๐š›๐š˜๐š—๐š๐šŽ๐š—๐š (9)
      • ๐š๐šŽ๐šŠ๐šŒ๐š (4)
      • ๐š…๐šž๐šŽ.๐š“๐šœ (2)
      • ๐™ท๐šž๐š๐š˜ (3)
    • ๐™ฐ๐š•๐š๐š˜๐š›๐š’๐š๐š‘๐š– (45) N
      • ๐™ฟ๐š›๐š˜๐š๐š›๐šŠ๐š–๐š–๐šŽ๐š›๐šœ (6)
      • ๐™ฑ๐šŠ๐šŽ๐š”๐š“๐š˜๐š˜๐š— (37) N
    • ๐™ณ๐™ฐ๐šƒ๐™ฐ๐™ฑ๐™ฐ๐š‚๐™ด (19)
      • ๐š‚๐š€๐™ป (1)
      • ๐™ฟ๐š˜๐šœ๐š๐š๐š›๐šŽ๐š‚๐š€๐™ป (1)
      • ๐™ผ๐šข๐š‚๐š€๐™ป (3)
      • ๐™พ๐š›๐šŠ๐šŒ๐š•๐šŽ (1)
      • ๐™ผ๐šŠ๐š›๐š’๐šŠ๐™ณ๐™ฑ (1)
      • ๐™ฟ๐š›๐š˜๐š๐š›๐šŠ๐š–๐š–๐šŽ๐š›๐šœ (1)
    • ๐™ณ๐šŽ๐šŸ๐šŽ๐š•๐š˜๐š™๐š–๐šŽ๐š—๐š ๐šƒ๐š˜๐š˜๐š•๐šœ (14) N
      • ๐™ธ๐š—๐š๐šŽ๐š•๐š•๐š’๐™น (0)
      • ๐™ด๐šŒ๐š•๐š’๐š™๐šœ๐šŽ (9)
      • ๐š…๐š‚๐™ฒ๐š˜๐š๐šŽ (1)
      • ๐™ฑ๐šž๐š’๐š•๐š ๐š‚๐šŒ๐š›๐š’๐š™๐š๐šœ (1)
    • ๐š…๐šŽ๐š›๐šœ๐š’๐š˜๐š— ๐™ฒ๐š˜๐š—๐š๐š›๐š˜๐š• (15)
      • ๐™ถ๐š’๐š (4)
      • ๐™ถ๐š’๐š๐™ท๐šž๐š‹ (6)
      • ๐š‚๐š…๐™ฝ (5)
    • ๋ฐฐํฌ ๋ฐ ์ธํ”„๋ผ (2)
      • ๐™ฐ๐š†๐š‚ (2)
    • ๐™ธ๐šƒ (10)
      • ๐š‚๐š…๐™ฝ (0)
    • ํ™˜๊ฒฝ์„ค์ • (2)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

  • spring
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • BAEKJOON
  • html
  • Java
  • PostgreSQL
  • JavaScript
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
  • ์ž๋ฐ”
  • php
  • ์ฝ”ํ…Œ
  • Hugo
  • React
  • ํ‹ฐ์Šคํ† ๋ฆฌ์ฑŒ๋ฆฐ์ง€
  • ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
  • ์ž๋ฐ”์˜์ •์„
  • ๋ฐฑ์ค€
  • ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
  • ์˜ค๋ธ”์™„
  • ์ดํด๋ฆฝ์Šค

์ตœ๊ทผ ๋Œ“๊ธ€

์ตœ๊ทผ ๊ธ€

hELLO ยท Designed By ์ •์ƒ์šฐ.v4.3.0
ํ•ด๋ฒ„๋‹ˆ
[React] Zustand๋กœ ๋กœ๊ทธ์ธ ์ƒํƒœ ๊ด€๋ฆฌํ•˜๊ธฐ: ์ฝ”๋“œ + ๊ฐœ๋… ์„ค๋ช…
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”

๋‹จ์ถ•ํ‚ค

๋‚ด ๋ธ”๋กœ๊ทธ

๋‚ด ๋ธ”๋กœ๊ทธ - ๊ด€๋ฆฌ์ž ํ™ˆ ์ „ํ™˜
Q
Q
์ƒˆ ๊ธ€ ์“ฐ๊ธฐ
W
W

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€

๊ธ€ ์ˆ˜์ • (๊ถŒํ•œ ์žˆ๋Š” ๊ฒฝ์šฐ)
E
E
๋Œ“๊ธ€ ์˜์—ญ์œผ๋กœ ์ด๋™
C
C

๋ชจ๋“  ์˜์—ญ

์ด ํŽ˜์ด์ง€์˜ URL ๋ณต์‚ฌ
S
S
๋งจ ์œ„๋กœ ์ด๋™
T
T
ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ ์ด๋™
H
H
๋‹จ์ถ•ํ‚ค ์•ˆ๋‚ด
Shift + /
โ‡ง + /

* ๋‹จ์ถ•ํ‚ค๋Š” ํ•œ๊ธ€/์˜๋ฌธ ๋Œ€์†Œ๋ฌธ์ž๋กœ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ํ‹ฐ์Šคํ† ๋ฆฌ ๊ธฐ๋ณธ ๋„๋ฉ”์ธ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.