๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev

[spotify-api] VINYLIFY : ์Šคํฌํ‹ฐํŒŒ์ด apiํ™œ์šฉํ•œ ๊ฒ€์ƒ‰ + ์žฌ์ƒ ํ”„๋กœ์ ํŠธ(5) react router ์„ค์ •

[์ด์ „๊ธ€] 2024.08.08 - [๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev] - [spotify-api] VINYLIFY : ์Šคํฌํ‹ฐํŒŒ์ด apiํ™œ์šฉํ•œ ๊ฒ€์ƒ‰ + ์žฌ์ƒ ํ”„๋กœ์ ํŠธ(4) eslint + prettier + commitlint ์„ค์ • (+husky)

 

[spotify-api] VINYLIFY : ์Šคํฌํ‹ฐํŒŒ์ด apiํ™œ์šฉํ•œ ๊ฒ€์ƒ‰ + ์žฌ์ƒ ํ”„๋กœ์ ํŠธ(4) eslint + prettier + commitlint ์„ค์ • (+hu

2024.06.12 - [๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev] - [spotify-api] VINYLIFY : ์Šคํฌํ‹ฐํŒŒ์ด apiํ™œ์šฉํ•œ ๊ฒ€์ƒ‰ + ์žฌ์ƒ ํ”„๋กœ์ ํŠธ(3) ์ค€๋น„๋ฌผ: authorization์„ ๋‹ด๋‹นํ•  ์„œ๋ฒ„ ์ฝ”๋“œ [spotify-api] VINYLIFY : ์Šคํฌํ‹ฐํŒŒ์ด apiํ™œ์šฉํ•œ ๊ฒ€์ƒ‰ + ์žฌ์ƒ ํ”„๋กœ์ 

pyotato-dev.tistory.com

์ €๋ฒˆ ๊ธ€์—์„œ๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ํ•ด์ค„ Prettier, ๋ฆฐํŠธ๋ฅผ ํ•ด์ค„ Eslint, ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฆฐํŠธํ•ด์ค„ commitlint๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ทธ๋ฆฌ๊ณ  ์„ค์ •์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์งœ๊ธฐ ์ „์˜ ์‚ฌ์ „ ์ค€๋น„๋Š” ์™„๋ฃŒํ–ˆ๋‹ค. 
๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป ์˜ค๋Š˜์€ react router ์„ค์ •์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…

๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋Š” "ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…"์„ ํ•ด์ค€๋‹ค.

์ „ํ†ต์ ์ธ ์›น์‚ฌ์ดํŠธ์˜ ๋ธŒ๋ผ์šฐ์ €๋Š” ์›น ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ document ์š”์ฒญ์„ ํ•œ ํ›„,

์‘๋‹ต์œผ๋กœ ๋ฐ›์€ css์™€ js asset๋“ฑ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํ‰๊ฐ€ํ•ด์„œ HTML ๋žœ๋”๋ฅผ ํ•œ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ๊ทธ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ์ด ๊ณผ์ •์„ ์š”์ฒญ์„ ํ•˜๋Š” ์ฒซ ๋‹จ๊ณ„๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•œ๋‹ค.

 

๋ฐ˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…์€ ์„œ๋ฒ„ํ•œํ…Œ document ์š”์ฒญ์„ ํ•  ํ•„์š” ์—†์ด,

๋ฐ”๋กœ ์ƒˆ๋กœ์šด UI ์ผ๋ถ€๋ฅผ ๋žœ๋”ํ•˜๊ณ  fetch๋ฅผ ํ†ตํ•ด์„œ ์ƒˆ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋กœ ์—…๋ฐ์ดํŠธํ•  ๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด document๋ฅผ ์š”์ฒญํ•˜๊ฑฐ๋‚˜, css/js์— ๋Œ€ํ•œ ์žฌ์—ฐ์‚ฐ์„ ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋–„๋ฌธ์— ์‚ฌ์šฉ์ž๋“ค์€ ๋” ๋น ๋ฅธ ์œ ์ € ๊ฒฝํ—˜์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…์€ Router๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Link์™€ <Form/>์œผ๋กœ  link/submitํ•ด์„œ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ค์น˜

yarn add react-router-dom

์„ค์ •

  • constants/url.ts : url๊ด€๋ จ ์ƒ์ˆ˜๋“ค์„ ๋ชจ์•„๋‘” ํŒŒ์ผ. page์— ๊ด€ํ•œ ๊ฒฝ๋กœ๋ฅผ ์ด ํŒŒ์ผ์— ๋ชจ์•„๋‘์—ˆ๋‹ค.
export const PAGE = {
  MAIN: '/',
  ERROR: '/error',
  MYPAGE: '/mypage',
  SEARCH: '/search',
  MUSIC_INFO: '/music-info',
  LOGGED_IN: '/me',
};
  • routes/router.tsx : createBroswerRouter ์„ค์ •์„ ํ•ด์ฃผ์ž.
import { PAGE } from '@/constants/url';
import { BaseLayout } from '@/layout/BaseLayout';
import ErrorPage from '@/pages/ErrorPage';
import MainPage from '@/pages/MainPage';
import MusicInfoPage from '@/pages/MusicInfoPage';

import NotFoundPage from '@/pages/NotFoundPage';
import SearchPage from '@/pages/SearchPage';
import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter([
  {
    element: <BaseLayout />,
    children: [
      {
        path: PAGE.MAIN,
        element: <MainPage />,
        errorElement: <ErrorPage />,
      },
      {
        path: PAGE.LOGGED_IN,
        element: <MainPage />,
        children: [{ path: PAGE.LOGGED_IN, element: <MainPage /> }],
        errorElement: <ErrorPage />,
      },
      {
        path: PAGE.MUSIC_INFO,
        element: <MusicInfoPage />,
        errorElement: <ErrorPage />,
      },
      {
        path: PAGE.SEARCH,
        element: <SearchPage />,
        errorElement: <ErrorPage />,
      },

      {
        path: '*', // ์œ„์˜ ํŽ˜์ด์ง€ ์ด์™ธ์˜ ๊ฒฝ์šฐ๋Š” notfound (404) ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜์ž.
        element: <NotFoundPage />,
      },
    ],
    errorElement: <ErrorPage />,
  },
]);
export default router;
  • ์œ„์˜ ์„ค์ •๋“ค์„ ๋ณด๋ฉด
    • element ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ์‹ธ์ค„ ๋ ˆ์ด์•„์›ƒ์ด๋‹ค. 
    • ๊ฐ children์€ Outlet์œผ๋กœ ๊ฐ route์— ํ•ด๋‹นํ•˜๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
  • layout/BaseLayout.tsx
import { Outlet } from 'react-router-dom';
import Header from './Header';

export const BaseLayout = () => {
  return (
    <>
      <Header />
      <Outlet />
    </>
  );
};
  • ๋ผ์šฐํ„ฐ, tanstack query ๋“ฑ์€ ์ตœ์ƒ์œ„์— ์ œ๊ณตํ•ด์ค„ ๊ธฐ๋Šฅ๋“ค์„ provider์— ๋ชจ์•„๋‘˜ ์˜ˆ์ •์ด๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒŒ์ผ์— ์ถ”๊ฐ€๋ฅผ ํ•ด์ฃผ์ž.
  • providers/router.tsx
import router from '@/routes/router';
import { RouterProvider } from 'react-router-dom';

const Router = () => {
  return <RouterProvider router={router} />;
};

export default Router;
  • providers/index.tsx
import Router from './router';
 
const Providers = () => {
  return (
      <Router />
  );
};

export default Providers;
  • App.tsx
import './app.scss';
import Providers from './providers'; 
function App() {
  return <Providers></Providers>;
}

export default App;

 

์ด์ œ ํŽ˜์ด์ง€ url์— ๋”ฐ๋ผ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์ธ ํŽ˜์ด์ง€ (/), ํ˜„์žฌ ์žฌ์ƒ ํŠธ๋ž™ ํŽ˜์ด์ง€ (/music-info)
๊ฒ€์ƒ‰ ํŽ˜์ด์ง€(/search), not found (404) ํŽ˜์ด์ง€


 ๐Ÿ“š References

https://reactrouter.com/en/main

 

Home v6.26.0 | React Router

 

reactrouter.com