[๐Ÿ› ๏ธ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…] ์ธ์ฆ,์ธ๊ฐ€ ํ”„๋กœ์ ํŠธ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ทธ ์™ธ ์ด์Šˆ

gimmariยท2024๋…„ 9์›” 19์ผ
1

๐Ÿ“ React

๋ชฉ๋ก ๋ณด๊ธฐ
21/24
post-thumbnail
  1. ์‘๋‹ต ๊ตฌ์กฐ ์ดํ•ด์˜ ์–ด๋ ค์›€:
    updateProfile ํ•จ์ˆ˜์—์„œ API ํ˜ธ์ถœ ํ›„ response.data ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•˜์Œ.
    Network ํƒญ์„ ํ†ตํ•ด API ์‘๋‹ต์„ ํ™•์ธํ–ˆ๋”๋‹ˆ { accessToken, avatar, nickname, success, userId } ํ˜•ํƒœ์˜€์Œ.
    ์ด๋กœ ์ธํ•ด response.nickname๊ณผ response.data.nickname ์ค‘ ์–ด๋А ์ชฝ์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ํ˜ผ๋ž€์Šค๋Ÿฌ์› ์Œ.

  2. ์ƒํƒœ ๊ด€๋ฆฌ ์ด์Šˆ:
    ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜์—์„œ ์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜๋„๋ก ๋กœ์ง์„ ์ˆ˜์ •ํ–ˆ์Œ.
    ์˜ˆ๋ฅผ ๋“ค์–ด, setUser((prevUser) => ({ ...prevUser, nickname: response.nickname }))์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด์ „ ์‚ฌ์šฉ์ž ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ–ˆ์Œ.

  3. ํŠน์ • ํŽ˜์ด์ง€์—์„œ์˜ ํ—ค๋”, ๋ผ์šฐํŒ… ๋ฌธ์ œ:
    ํ—ค๋”์™€ ๋ผ์šฐํŒ… ์„ค์ •์„ ์ง„ํ–‰ํ• ๋•Œ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋Š” ํ—ค๋”์™€ ์•„๋‹Œ ๊ณตํ†ต ํ—ค๋”๋ฅผ ๊ฐ€์ง€๋Š” ํŽ˜์ด์ง€์— ๋…ผ์˜๊ฐ€ ํ•„์š”ํ–ˆ์Œ.

  4. ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ๋ฌธ์ œ:
    ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ npm๊ณผ yarn ๊ฐ™์€ ์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด, ์˜์กด์„ฑ ๋ฌธ์ œ์™€ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ–ˆ์Œ.

  5. ์Šคํƒ€์ผ ๋ณ€๊ฒฝ์˜ ์–ด๋ ค์›€:
    ํ”„๋กœ์ ํŠธ์—์„œ Tailwind CSS๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ, ํŒ€์›์ด styled-components๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํƒ€์ผ๋ง์„ ํ•ด์„œ, ๋‚˜์ค‘์— Tailwind ์Šคํƒ€์ผ์„ styled-components๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ์–ด๋ ค์›€์ด ์žˆ์—ˆ์Œ.


๋А๋‚€์ 

  • ํŒ€์› ๊ฐ„์˜ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ๋ฐฉ์‹, CSS ์Šคํƒ€์ผ๋ง ํ†ต์ผ ํ•„์š”์„ฑ์„ ๋А๊ผˆ์Œ.
  • ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ๋„ ์‚ฌ์šฉ๋˜๋Š” ๋กœ์ง์„ ๋…ผ์˜ํ•  ํ•„์š”์„ฑ์„ ๋А๊ผˆ์Œ.

zustand ์‚ฌ์šฉ๋ฒ•

1. Zustand Store ๋งŒ๋“ค๊ธฐ

Zustand๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ store ์ƒ์„ฑ

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

const useUserStore = create(
  persist(
    (set) => ({
      user: null,
      setUser: (userData) => set({ user: userData }),
      clearUser: () => set({ user: null })
    }),
    {
      name: 'user-storage', // localStorage์— ์ €์žฅ๋  ํ‚ค์˜ ์ด๋ฆ„
      getStorage: () => localStorage // localStorage๋ฅผ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉ
    }
  )
);

export default useUserStore;

2. Zustand Store ์‚ฌ์šฉํ•˜๊ธฐ

store๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด useUserStore ํ›… ๋„ฃ๊ธฐ

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

const useUserStore = create(
  persist(
    (set) => ({
      user: null, // ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๊ณณ
      accessToken: null, // ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ† ํฐ
      setUser: (userData) => set({ user: userData }), // ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ํ•จ์ˆ˜
      setAccessToken: (token) => set({ accessToken: token }), // ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ํ•จ์ˆ˜
      clearUser: () => set({ user: null, accessToken: null }) // ์‚ฌ์šฉ์ž ์ •๋ณด์™€ ํ† ํฐ์„ ์ง€์šฐ๋Š” ํ•จ์ˆ˜
    }),
    {
      name: "user-storage", // ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ด๋ฆ„
      getStorage: () => localStorage // ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ์ €์žฅ์†Œ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€
    }
  )
);

export default useUserStore;

3. ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐ ๋ฐ์ดํ„ฐ ์ €์žฅ

  • ์ƒํƒœ์˜ ๋ถ„๋ฅ˜์™€ ์—ญํ• 
  1. user ์ƒํƒœ:

    • ์—ญํ• : ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ID, ๋‹‰๋„ค์ž„, ํ”„๋กœํ•„ ์‚ฌ์ง„ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ๋‹ด์Šต๋‹ˆ๋‹ค.
    • ์šฉ๋„: ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ์ ์ธ ์ •๋ณด์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์ด ์ƒํƒœ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋ฅผ ํ†ตํ•ด UI์—์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งž๋Š” ๋งž์ถคํ˜• ์ฝ˜ํ…์ธ ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ: ๋กœ๊ทธ์ธ ํ›„ user ์ƒํƒœ์— ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ , ์ด ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ํ™”๋ฉด์— ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  2. accessToken ์ƒํƒœ:

    • ์—ญํ• : ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ API ์š”์ฒญ ์‹œ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ์„ ํ™•์ธํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ์šฉ๋„: API ์š”์ฒญ์—์„œ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด accessToken์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํ† ํฐ์ด ์œ ํšจํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆ๋œ ์ƒํƒœ๋กœ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ: ๋กœ๊ทธ์ธ ํ›„ accessToken์„ ์ €์žฅํ•˜๊ณ , ์ด ํ† ํฐ์„ API ์š”์ฒญ์˜ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜
  1. setUser ํ•จ์ˆ˜:

    • ์—ญํ• : user ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ์šฉ๋„: ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜๊ฑฐ๋‚˜ ํšŒ์›๊ฐ€์ž…ํ•  ๋•Œ, ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ user ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ: ๋กœ๊ทธ์ธ ํ›„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ setUser(userData)๋ฅผ ํ†ตํ•ด user ์ƒํƒœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  2. setAccessToken ํ•จ์ˆ˜:

    • ์—ญํ• : accessToken ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ์šฉ๋„: ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•  ๋•Œ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ† ํฐ์„ setAccessToken(token)์„ ํ†ตํ•ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ API ์š”์ฒญ ์‹œ ์ด ํ† ํฐ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ: ๋กœ๊ทธ์ธ ํ›„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ† ํฐ์„ setAccessToken(token)์„ ํ†ตํ•ด ์ƒํƒœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์š”์•ฝ

  • user: ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • accessToken: ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ํ† ํฐ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • setUser: ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  • setAccessToken: ์ธ์ฆ ํ† ํฐ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

4. ์‚ฌ์šฉ์ž ์ •๋ณด์™€ ์ƒํƒœ ์ „๋‹ฌ

์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, Zustand store์—์„œ ํ•„์š”ํ•œ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ปดํฌ๋„ŒํŠธ์˜ props๋‚˜ ์ง์ ‘ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๊ทธ์ธ ์ƒํƒœ์— ๋”ฐ๋ผ ํ—ค๋”๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ:

const Layout = () => {
  const { user, setUser } = useUserStore();

  const handleLogout = () => {
    setUser(null);
    localStorage.removeItem("accessToken");
  };

  return (
    <header>
      {user ? (
        <div>
          <p>{`${user.nickname}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`}</p>
          <button onClick={handleLogout}>๋กœ๊ทธ์•„์›ƒ</button>
        </div>
      ) : (
        <div>
          <Link to="/login">๋กœ๊ทธ์ธ</Link>
          <Link to="/signup">ํšŒ์›๊ฐ€์ž…</Link>
        </div>
      )}
    </header>
  );
};

์ธ์ฆ ์ธ๊ฐ€์—์„œ ์ค‘์š”ํ•œ ํ† ํฐ ์‚ฌ์šฉ

  1. ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•
  2. ์ €์žฅ๋œ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•˜๋Š” ๋ฐฉ๋ฒ•

1. AccessToken ์ €์žฅํ•˜๊ธฐ

๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋˜๋Š” ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€์— ํ† ํฐ ์ €์žฅํ•˜๊ธฐ

  • ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€: ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•˜๋”๋ผ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€: ๋ธŒ๋ผ์šฐ์ € ์„ธ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋ณดํ†ต, ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ ค๋ฉด ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๊ณ ์นจํ•˜๊ฑฐ๋‚˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋‹ซ์•˜๋‹ค ๋‹ค์‹œ ์—ด์–ด๋„ ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const handleLogin = async (formData) => {
  try {
    const loginData = await login(formData);
    localStorage.setItem("accessToken", loginData.accessToken);

  } catch (error) {
    alert("๋กœ๊ทธ์ธ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.");
  }
};

์œ„ ์ฝ”๋“œ์—์„œ๋Š” login API ํ˜ธ์ถœ ํ›„, ๋ฐ›์€ accessToken์„ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

2. ์ €์žฅ๋œ AccessToken์œผ๋กœ ์ƒํƒœ ๋ณต์›ํ•˜๊ธฐ

ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๊ณ ์น˜๊ฑฐ๋‚˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์žฌ์‹œ์ž‘ํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ๋Š” ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ์ €์žฅ๋œ accessToken์„ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์•ฑ์ด ์‹œ์ž‘ํ•  ๋•Œ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ํ† ํฐ์„ ํ™•์ธํ•˜๊ณ  ์ƒํƒœ๋ฅผ ๋ณต์›ํ•˜๋Š” ๋กœ์ง์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Zustand๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ

  1. Zustand Store ์„ค์ •

    Zustand store๋ฅผ ์„ค์ •ํ•  ๋•Œ, accessToken์„ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ์ฝ์–ด์™€ ์ƒํƒœ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

    import { create } from "zustand";
    import { persist } from "zustand/middleware";
    
    const useUserStore = create(
      persist(
        (set) => ({
          user: null,
          accessToken: localStorage.getItem("accessToken") || null, // ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ accessToken ์ฝ๊ธฐ
          setUser: (userData) => set({ user: userData }),
          setAccessToken: (token) => {
            localStorage.setItem("accessToken", token); // ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ํ† ํฐ ์ €์žฅ
            set({ accessToken: token });
          },
          clearUser: () => {
            localStorage.removeItem("accessToken"); // ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ํ† ํฐ ์ œ๊ฑฐ
            set({ user: null, accessToken: null });
          }
        }),
        {
          name: "user-storage",
          getStorage: () => localStorage
        }
      )
    );
    
    export default useUserStore;
  2. ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ ์‚ฌ์šฉํ•˜๊ธฐ

    ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ, accessToken์ด ์ €์žฅ๋œ ์ƒํƒœ์ธ์ง€ ํ™•์ธํ•˜๊ณ , ํ•„์š”ํ•œ ๊ฒฝ์šฐ API ํ˜ธ์ถœ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    import React, { useEffect } from "react";
    import useUserStore from "./path/to/useUserStore";
    import { getUserProfile } from "./api/auth";
    
    const App = () => {
      const { user, accessToken, setUser } = useUserStore();
    
      useEffect(() => {
        if (accessToken) {
          // accessToken์ด ์กด์žฌํ•˜๋ฉด, API๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
          const fetchUserProfile = async () => {
            try {
              const userProfile = await getUserProfile(accessToken);
              setUser(userProfile);
            } catch (error) {
              console.error("์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ:", error);
            }
          };
    
          fetchUserProfile();
        }
      }, [accessToken, setUser]);
    
      return (
        <div>
          {user ? <p>Welcome, {user.nickname}!</p> : <p>Please log in.</p>}
        </div>
      );
    };
    
    export default App;

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ฉด, ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ accessToken์„ ์ฝ์–ด์™€ ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋ณ€์ˆ˜๋ช… ํ—ท๊ฐˆ๋ฆฌ๋Š” ์ด์Šˆ

import axios from "axios";

const API_URL = "https://moneyfulpublicpolicy.co.kr";

export const register = async (userData) => {
  const response = await axios.post(`${API_URL}/register`, userData);
  return response.data;
};

export const login = async (userData) => {
  const response = await axios.post(`${API_URL}/login`, userData);
  return response.data;
};
...
const useUserStore = create(
  persist(
    (set) => ({
      user: null,
      accessToken: null,
      setUser: (userData) => set({ user: userData })
      // userData๋ฅผ user ์ƒํƒœ์— ์ €์žฅํ•˜๋ ค๊ณ 
      // { user: userData }๋Š” ์ƒˆ๋กœ์šด ์ƒํƒœ ๊ฐ์ฒด๋กœ, user๋ผ๋Š” ์†์„ฑ์„ userData ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๊ฒ ๋‹ค๋Š” ๋œป.
      // ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด user์—๋Š” ์ด์ œ ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค
      ...

1. user vs. userData์˜ ์—ญํ•  ์ฐจ์ด

  • user: ์ƒํƒœ ๊ด€๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ ๊ฐ’์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, Zustand์—์„œ ๊ด€๋ฆฌํ•˜๋Š” user๋Š” ๋กœ๊ทธ์ธํ•œ ํ›„ ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.
  • userData: ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋‚˜ ์™ธ๋ถ€์—์„œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๊ทธ์ธ API์—์„œ ๋ฐ˜ํ™˜๋œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ์ฒด๋ฅผ ๋ฐ›์„ ๋•Œ userData๋ผ๋Š” ์ด๋ฆ„์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ํ•จ์ˆ˜์—์„œ ์ผ์‹œ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.

์ฆ‰, user๋Š” ์•ฑ ๋‚ด์—์„œ ์ „์—ญ ์ƒํƒœ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด์ด๊ณ , userData๋Š” ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๋“ค์–ด์˜จ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž ์ •๋ณด์ž…๋‹ˆ๋‹ค.

2. ์ด๋ฆ„์„ ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  • user๋Š” Zustand์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ƒํƒœ (์ฆ‰, ํ˜„์žฌ ์‚ฌ์šฉ์ž ์ƒํƒœ)
  • userData๋Š” ํ•จ์ˆ˜๋‚˜ API์—์„œ ๋ฐ›์•„์˜จ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ(์ž…๋ ฅ๊ฐ’)

์˜ˆ์‹œ๋กœ ์ƒํ™ฉ์„ ๋‚˜๋ˆ  ๋ณด๋ฉด:

์ƒํ™ฉ 1: ๋กœ๊ทธ์ธ API์—์„œ userData๋ฅผ ๋ฐ›์•„์™€ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ

const login = async (credentials) => {
  const userData = await api.login(credentials); // ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ์‚ฌ์šฉ์ž ์ •๋ณด
  setUser(userData); // ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒํƒœ๋กœ ์ €์žฅ
}

์—ฌ๊ธฐ์„œ userData๋Š” API๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜จ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž ์ •๋ณด์ด๊ณ , setUser๋ฅผ ํ†ตํ•ด ์ด ๋ฐ์ดํ„ฐ๋ฅผ Zustand์—์„œ ๊ด€๋ฆฌํ•˜๋Š” user ์ƒํƒœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ƒํ™ฉ 2: ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ›„ user ์‚ฌ์šฉ

const { user } = useUserStore(); // Zustand์—์„œ ์ƒํƒœ ๊ฐ€์ ธ์˜ค๊ธฐ

console.log(user); // ์ด๊ฑด ํ˜„์žฌ ์ €์žฅ๋œ ์‚ฌ์šฉ์ž ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

์ด์ฒ˜๋Ÿผ userData๋Š” ์™ธ๋ถ€์—์„œ ์ƒˆ๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์ด๊ณ , user๋Š” ์ด๋ฏธ ์ €์žฅ๋œ ์ƒํƒœ ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ๋‹ค๋ฅด๊ฒŒ ํ•ด์„œ ํ˜ผ๋ž€์„ ์ค„์ธ๋‹ค!!


์š”์•ฝ:

  • user๋Š” ์ „์—ญ ์ƒํƒœ๋กœ ์•ฑ ์ „์ฒด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด.
  • userData๋Š” ์™ธ๋ถ€์—์„œ ๋ฐ›์•„์˜ค๋Š”(api) ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ.
  • ์ด๋ฆ„์„ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์—์„œ ๊ฐ’์˜ ์ถœ์ฒ˜๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
profile
๊น€๋งˆ๋ฆฌ์˜ ๊ฐœ๋ฐœ.๋กœ๊ทธ

0๊ฐœ์˜ ๋Œ“๊ธ€