개발/개발로그

[React] 간단한 성냥퍼즐 웹 서비스 만들기 2일차 (react-router-dom)

seungho-dev 2024. 11. 13. 11:26

성냥이.png

이번 프로젝트 아이콘을 한번 만들어 보았다. 살짝 뾰로통한게 포인트!

 

프로젝트 세팅을 간단하게 끝내고 이제 라우팅 설정을 하려고 하다가

내가 알던 컨포넌트기반 라우팅에서 router 객체로 관리하도록 바뀐 부분이 있어 

아래 heropy님 블로그를 참고해 만들게 되었다.  굉장히 설명이 잘되어있다.

https://www.heropy.dev/p/9tesDt 

개인적인 공부를 위해 작성하는 블로그입니다. 혹시라도 잘못되거나 부족한 부분이 있다면 댓글로 알려주시면 감사하겠습니다.

 


💁🏻 React Router를 사용하는 이유는?

기존 SSR방식에서는 라우팅을 통해 서버로 해당 자원을 요청해 페이지를 전환했지만 ReactCSR방식을 사용하며 VDOM을 이용한 SPA(Single Page Application)에 특화되어 있기 때문에 페이지 전환 시 새로고침이 발생하면 Virtual DOM을 제대로 활용하기 어렵다. 따라서 <a> 태그 대신 Link 컴포넌트를 사용하는 등 정적, 동적 라우팅 모두 'react-router-dom'에서 제공하는 기능으로 쉽게 구현할 수 있다.

 

👨🏻‍💻 JSX 라우팅 방식과 객체 기반 라우팅 방식의 차이

특징 <Router>, <Routes>, <Route> 방식 createBrowserRouter 방식
설정 방식 JSX 컴포넌트 기반 JavaScript 객체 기반
라우팅 정의 위치 JSX 내부 별도의 router 객체로 분리
데이터 로딩 및 처리 없음 (수동으로 설정) loader, action으로 라우트별 데이터 로드
라우트 보호 및 오류 처리 직접 구현 필요 errorElement 지원
코드 구조 라우트 구조가 시각적으로 직관적 코드가 더 분리되어 유지보수성 향상
SSR 및 클라이언트 성능 최적화 기본 지원 없음 라우트별 데이터 로딩을 통한 최적화 가능

 

✏︎ React Router v6.4 이전 방식

// src/App.jsx
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import Layout from './components/Layout'
import Home from './pages/Home'
import PuzzleDetail from './pages/PuzzleDetail'
import Profile from './pages/Profile'

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="puzzle/:puzzleId" element={<PuzzleDetail />} />
          <Route path="profile" element={<Profile />} />
        </Route>
      </Routes>
    </Router>
  )
}

export default App

 

✏︎ React Router v6.4

※기존 방식처럼 사용해 creactRoutesFromElement() 으로 업데이트하는 방법도 공식문서에서 소개하고 있다.

가장 최상위의 main.js(or index.js)에서 createBrowserRouter를 정의하고 RouterProvider를 추가하면 된다.

import * as React from 'react'
import * as ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import "./index.css"

// 페이지 및 레이아웃 컴포넌트 import
import Root from './routes/root'
import Home from './routes/home'
import ErrorPage from './routes/error'
import PuzzleDetail from './routes/puzzle-detail'
import Profile from './routes/profile'

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        index: true,
        element: <Home />
      },
      {
        path: "puzzle/:puzzleId",
        element: <PuzzleDetail/>
      },
      {
        path: "profile",
        element: <Profile />,
      }
    ]
  }
])

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
)
ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider 
      router={router}
      fallbackElement={<div>로딩중...</div>}
    />
  </React.StrictMode>
)

이런식으로 fallbackElement를 넣어줄 수 도 있다.

 

읽어주셔서 감사합니다