๐Ÿ“– TIL - ํ”„๋กœ์ ํŠธ๋ฅผ ๋งˆ๋ฌด๋ฆฌ ํ•˜๋ฉฐ.. ๊ธฐ๋กํ•  ๋งŒํ•œ ๊ธฐ์ˆ ๋“ค ๋„์ ๋„์ 

์Š˜ยท2025๋…„ 3์›” 6์ผ

๐Ÿ“– TIL

๋ชฉ๋ก ๋ณด๊ธฐ
68/90

์˜ค๋Š˜์€ ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์—…ํ•˜๋ฉด์„œ ๋ช‡ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ๋“ค์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค...!
(์–ด์ œ velog ์„œ๋ฒ„ ํ„ฐ์ ธ์„œ ์ด์ œ์•ผ ์˜ฌ๋ฆฌ๋Š” ์ˆ˜์š”์ผ TIL!)

๐Ÿ“Œ ๋ผ์šฐํ„ฐ์˜ ๋‘ ์–ผ๊ตด: BrowserRouter vs createBrowserRouter

๊ธฐ์กด์— ํ•ญ์ƒ ์ผ๋˜ BrowserRouter์™€ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ ๋œ createBrowserRouter์˜ ์ฐจ์ด์ ์„ ๋ฐฐ์› ๋‹ค.

์˜ˆ์ „์—๋Š” ํ•ญ์ƒ ์ด๋ ‡๊ฒŒ ์ผ๋Š”๋ฐ:

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/product/:id" element={<ProductDetail />} />
  </Routes>
</BrowserRouter>

createBrowserRouter๋Š” ๊ฐ์ฒด ์Šคํƒ€์ผ๋กœ ๋ผ์šฐํŒ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />
  },
  {
    path: "/product/:id",
    element: <ProductDetail />,
    loader: productLoader,
    errorElement: <ErrorPage />
  }
]);

์ด ๋ฐฉ์‹์˜ ์ง„์งœ ์žฅ์ ์€ loader์™€ errorElement ๊ฐ™์€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. ํŠนํžˆ loader๋Š” ํฅ๋ฏธ๋กœ์› ๋Š”๋ฐ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์–ด์„œ ๋กœ๋”ฉ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ๋” ํŽธํ•ด์งˆ ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿ’ก useLoaderData๋กœ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉํ•˜๊ธฐ

loader์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋Š” useLoaderData ํ›…์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค:

function ProductDetail() {
  const product = useLoaderData();
  
  // ์ด๋ฏธ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.price}์›</p>
    </div>
  );
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด useEffect์™€ useState๋กœ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•ด์งˆ ๊ฒƒ ๊ฐ™๋‹ค.

โœจ Zustand์—์„œ persist ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์šฉํ•˜๊ธฐ

Zustand ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ localStorage์— ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋ฐฐ์› ๋‹ค. persist ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋œ๋‹ค:

const useAuthStore = create(
  persist(
    (set) => ({
      user: null,
      login: (user) => set({ user }),
      logout: () => set({ user: null })
    }),
    { name: 'auth-storage' }
  )
);

์žฌ๋ฐŒ๋Š” ๊ฑด partialize๋ผ๋Š” ๊ธฐ๋Šฅ๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ. ๋ชจ๋“  ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ๋ถ€๋ถ„๋งŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค:

{
  name: 'user-storage',
  partialize: (state) => ({ user: state.user })  // user๋งŒ ์ €์žฅ, ๋‹ค๋ฅธ ์ƒํƒœ๋Š” ์ €์žฅ ์•ˆ ํ•จ
}

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

๐Ÿš€ react-cookie๋กœ ์ฟ ํ‚ค ๋‹ค๋ฃจ๊ธฐ

์ฟ ํ‚ค ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ react-cookie ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์•Œ๊ฒŒ ๋๋‹ค. ์ƒ๊ฐ๋ณด๋‹ค ์“ฐ๊ธฐ ์‰ฌ์› ๋‹ค:

const [cookies, setCookie, removeCookie] = useCookies(['token']);

// ์ฟ ํ‚ค ์„ค์ •
setCookie('token', 'my-token', { path: '/', maxAge: 3600 });

// ์ฟ ํ‚ค ์ฝ๊ธฐ
console.log(cookies.token);

// ์ฟ ํ‚ค ์‚ญ์ œ
removeCookie('token');

์ด์ „์—๋Š” document.cookie๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ๊ฑฐ๋‚˜ ๋ณ„๋„์˜ ์œ ํ‹ธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ผ๋Š”๋ฐ, ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ฐ๋ฉด ํ›จ์”ฌ ๊ฐ„๋‹จํ•ด์งˆ ๊ฒƒ ๊ฐ™๋‹ค.


์ด๋ฒˆ ์ฃผ์— ๋ฐฐ์šด ๊ฒƒ๋“ค์„ ์ถ”ํ›„ ์ ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋” ๊น”๋”ํ•ด์ง€๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๋„ ์ข‹์•„์งˆ ๊ฒƒ ๊ฐ™๋‹ค. ํŠนํžˆ createBrowserRouter์™€ loader ์กฐํ•ฉ์€ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ํŒจํ„ด์„ ์™„์ „ํžˆ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

profile
์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ์„ฑ์žฅ๊ธฐ ๊ธฐ๋ก๊ธฐ๋ก

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