본문 바로가기
📌 Front End/└ React

[React] 리액트 라우터 돔(React Router DOM) - BrowserRouter, Routes, Route, Outlet, Link, NavLink

by 쫄리_ 2024. 9. 4.
728x90
반응형

📌 리액트 라우터 돔(React Router DOM)

리액트 애플리케이션에서 페이지 간 이동(라우팅)을 쉽게 처리하기 위한 라이브러리입니다.
이 라이브러리를 사용하면 리액트 앱을 여러 페이지처럼 구성하고, 

각 페이지의 URL 경로를 정의할 수 있습니다.


📌 SPA(Single Page Application)

SPA는 기존 웹사이트와 다르게 한 개의 HTML 페이지에서 모든 작업을 처리하는 방식입니다.
일반 웹사이트는 사용자가 새로운 페이지로 이동할 때마다 페이지 전체를 새로고침하지만, 

SPA는 필요한 부분만 업데이트합니다.
이렇게 하면 속도도 빠르고 트래픽도 절약할 수 있습니다.


📌 React Router 주요 패키지

  • react-router : 웹과 앱 모두에서 사용할 수 있는 기본 라우터 라이브러리
  • react-router-dom : 웹 전용 라우터 라이브러리
  • react-router-native : 모바일 앱 전용 라우터 라이브러리

📌 React Router DOM 기본 사용법

리액트 애플리케이션에서 React Router DOM을 사용하면

URL에 따라 페이지를 변경할 수 있습니다.


✅ 리액트 라우터 라이브러리 설치

위 명령어로 react-router-dom 설치합니다.

이 라이브러리를 통해 리액트 애플리케이션에서 라우팅을 설정할 수 있습니다.

npm i react-router-dom

기본 세팅

📜app.tsx 같은 메인 파일에서 라우팅을 설정합니다.

<BrowserRouter> 앱의 최상단에 한 번만 사용해야 합니다.

 

🔎 모듈 3가지

  1. BrowserRouter : 라우팅을 설정하고 URL을 관리하는 최상위 컴포넌트
  2. Routes : 여러 Route를 포함하여 경로에 따라 렌더링할 컴포넌트를 결정
  3. Route : 특정 경로에 대한 컴포넌트를 정의하는 컴포넌트
import React from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom';

// ▶ 필요한 컴포넌트들을 가져와서 사용
import Home from './Home';
import About from './About';

function App() {
  return (
    <BrowserRouter>	{/* 1. BrowserRouter : 전체 라우팅을 감싸는 컴포넌트 */}
      <Routes>		{/* 2. Routes : 라우트들을 감싸는 컴포넌트 */}
        <Route path="/" element={<Home />} /> {/* 3. Route : 각 경로에 대한 컴포넌트 매핑 */}
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

 


🔎 각 모듈의 역할과 주요 속성

<BrowserRouter>
  <Routes>
     <Route path="경로" element={<보여 줄 컴포넌트 JSX />} />
  </Routes>
</BrowserRouter>

 

 <BrowserRouter> 

  • 라우팅을 설정하고 URL을 관리하는 최상위 컴포넌트입니다. 
    브라우저의 주소 표시줄과 애플리케이션의 라우트 상태를 동기화합니다.

  •  basename 
    모든 경로 앞에 붙는 기본 경로를 설정할 수 있습니다. 
    basename="/app"을 사용하면 모든 경로가 /app으로 시작합니다.

 <Routes> 

  • 여러 <Route>를 감싸서, 경로에 따라 올바르게 컴포넌트를 렌더링합니다. 

 <Route> 

  • 특정 경로(path)와 해당 경로에 매핑할 컴포넌트(element)를 지정
  • 경로는 위에서 아래로 순차적으로 비교됩니다.

  • 주요 속성들
    •  path  : 경로 설정 속성
      • 기본 방식 : /index (명시적 경로)
      • 와일드카드 방식 : * (모든 경로 포함) /index/* (특정 경로 아래의 모든 경로 포함)
      • 옵셔널 방식 : /index/test? (경로의 일부가 있을 수도, 없을 수도 있음)
      • 파라미터 방식 : /index/:id (경로의 일부를 변수처럼 사용)
    •  element  : 해당 경로로 이동했을 때 렌더링할 컴포넌트를 설정
    •  index  : 기본 경로(/)일 때 렌더링할 컴포넌트를 설정
    •  caseSensitive  : 경로의 대소문자를 구분할지 설정
    •  errorElement  : 경로로 이동할 때 에러가 발생하면 보여줄 컴포넌트를 설정

 중첩 라우트 

  • 경로가 비슷한 경우 중첩 라우트를 사용해 중복을 줄이고 효율적으로 관리할 수 있습니다.
  • 중첩 라우트는 부모 Route 안에 자식 Route를 중첩하여 정의할 수 있습니다.
  • Outlet 컴포넌트는 중첩된 경로의 렌더링 위치를 지정합니다.

 <Outlet /> 

  • 중첩 라우트를 사용하는 경우 자식 라우트를 표시하는 영역입니다. 
    부모 라우트의 요소 내에서 자식 라우트를 렌더링할 수 있게 합니다.

  • 주의사항
    • <Outlet />는 부모 <Route>의 element 속성 내에 포함되어야 합니다.
    • <Outlet />을 가진 부모 <Route>는 자식 <Route>들보다 위쪽에 위치해야 합니다. 
      즉, 자식 라우트는 부모 라우트 아래에 정의되어야 합니다.
    • <Outlet /> 안에 들어가는 경로는 앞에 /를 붙이지 않습니다. 
      /는 라우트에서 자동으로 붙기 때문입니다.

사용예시

/board 경로에서 <Outlet />을 통해

/board/write와 /board/read 경로의 자식 컴포넌트를 렌더링할 수 있습니다.

<Route path="/board" element={
  <>
    <header>헤더</header>
    <Outlet/> {/* 중첩된 Route가 렌더링될 위치 */}
    <footer>푸터</footer>
  </>
}>
  <Route path="write" element={<div>Write</div>}/> {/*  /board/write  */}
  <Route path="read" element={<div>Read</div>}/>   {/*  /board/read   */}
</Route>

 


 <Link>와 <NavLink> 

🔎 <Link>

<Link to="경로">링크 이름</Link>
  • 페이지 이동을 위한 링크 컴포넌트입니다. 
    페이지를 새로 고침하지 않고 경로만 변경합니다.

  • basename은 <BrowserRouter>에서 자동으로 처리되므로, 
    <Link>에서는 따로 신경 쓸 필요 없습니다.

  • 주요 속성
    •  to  : 이동할 경로 설정
    •  relative  : 경로를 절대 경로('path') 또는 상대 경로('route')로 설정
    •  preventScrollReset  : 페이지 이동 시 스크롤 위치가 초기화되지 않도록 설정
<Link to="/board/write">작성</Link>				{/* 절대 경로 */}
<Link to="write" relative='route'>작성</Link>			{/* 상대 경로 */}
<Link to="write" relative='route' preventScrollReset>작성</Link> {/* 상대 경로, 스크롤 위치 유지 */}
<Route path="/board" element={
  <>
    <header>헤더</header>
    <Outlet/> {/* 중첩된 라우트를 표시할 영역 */}
    <Link to="/board/write">작성</Link>	{/* 절대 경로 사용 */}
    <Link to="/board/read">읽기</Link>	{/* 절대 경로 사용 */}
    <footer>푸터</footer>
  </>
}>
  {/* Outlet 중첩된 경로 */}
  <Route path="write" element={<div>Write</div>} /> {/* 상대 경로 사용 : /board/write */}
  <Route path="read" element={<div>Read</div>} />   {/* 상대 경로 사용 : /board/read  */}
</Route>

{/* 상대 경로 사용 */}
<Link to="write" relative='route'>작성</Link>
<Link to="read" relative='route'>읽기</Link>

{/* 스크롤 위치 유지 */}
<Link to="write" relative='route' preventScrollReset>작성</Link>

 

🔎 <NavLink>

  • 현재 경로에 따라 동적 스타일링이 가능한 링크 컴포넌트
    <Link>와 비슷하지만, 활성화된 경로에 따라 스타일을 동적으로 변경할 수 있습니다.

  • 차이점
    style className 속성 값 함수로 작성할 수 있으며, 
    경로 상태에 따라 다양한 스타일을 적용할 수 있습니다.

  • 주요 속성
    •  isActive  : 경로가 활성화된 상태인지 확인
    •  isPending  : 경로가 로드 중인 상태인지 확인
    •  isTransitioning  : 경로 전환 중인지 확인
    •  end 
      to속성인 경로가 정확히 일치하는 경우
      활성화된 상태로 판단할 수 있게 합니다. (isActive를 구분하기 위한)
<NavLink to="read" style={({ isActive }) => ({
  color: isActive ? 'red' : 'black'
})}>읽기</NavLink> {/* 활성화된 경로에 따라 색상 변경 */}

<NavLink to="/a" end>홈</NavLink> {/* '/a'로 정확히 이동했을 때만 활성화 */}

 


✏️ React Router DOM 사용하기

import React from "react";
import { BrowserRouter, Routes, Route, Outlet, Link, NavLink } from 'react-router-dom';

export default function (){
    return <div>
        <BrowserRouter basename="/app">
            <Routes>
                <Route path="/" element={<div>기본 경로</div>}/>
                <Route path="/index" caseSensitive element={<div>인덱스 경로</div>}/>
                <Route path="/two/test?" 
                    element={<div></div>}
                    errorElement={<div>에러</div>}
                />
                <Route path="/board" element={
                    <>
                        <header>헤더</header>
                        <Outlet/>
                        <Link to="write" relative='route' preventScrollReset>작성</Link>
                        <NavLink to="read" style={({isActive, isPending, isTransitioning})=>{
                            return {};
                        }}>읽기</NavLink>
                        <footer>푸터</footer>
                    </>
                }>
                    <Route path="write" element={<div>Write</div>}/>
                    <Route path="read" element={<div>Read</div>}/>
                </Route>
            </Routes>
        </BrowserRouter>
    </div>
}

 


 

 

728x90
반응형