React Router Dom
2022. 12. 26. 21:42ㆍ프로그래밍/React
React Router Dom
웹 앱에서 동적 라우팅을 구현 가능하게 해주는 라이브러리
컴포넌트 기반 라우팅을 용이하게 함
Single Page Application (SPA)
리액트는 SPA이기 때문에 하나의 index.html 템플릿 파일을 가짐
자바스크립트를 이용해 컴포넌트들을 이 하나의 템플릿에 넣어 페이지를 변경함
이때 React Router Dom 라이브러리가 새 컴포넌트로 라우팅/검색을 하고 렌더링에 도움을 줌
React Router Dom 설치
npm install react-router-dom --save
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
설치 완료 후 앱 어디서든 React Router를 사용할 수 있도록
src/index.js 파일에서 BrowserRouter 로 루트 요소를 감싸줌
BrowserRouter
HTML5 History API를 사용해 (pushState, replaceState/popState 이벤트)
페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해줌 (UI를 URL과 동기화된 상태로 유지)
function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
</div>
);
}
Routes
앱에서 생성될 모든 개별 경로에 대한 컨테이너/상위 역할
자식 컴포넌트 중에서 매칭되는 첫번째 Route를 렌더링 함
Route
단일 경로를 만들 경우 사용됨
경로 이름이 백슬래시인 컴포넌트는 앱이 처음 로드될 때마다 먼저 렌더링 됨
path : 원하는 컴포넌트의 URL 경로 지정
element : 경로에 맞게 렌더링 되어야 하는 컴포넌트 지정
중첩 라우팅 (Nested Routes)
Route 안에 또 다른 Route 를 작성함
상세 페이지, 탭으로 구성된 페이지 구현에 용이함
부모 컴포넌트 안에서 자식 경로 요소가 렌더링 될 위치에 Outlet 사용
<BrowserRouter>
<Routes>
// App 컴포넌트에 Header/Footer 등 레이아웃
<Route path="/" element={<App />} />
// localhost:3000/ 경로 => Home 컴포넌트
<Route index element={<Home />}>
// localhost:3000/teams 경로 => Teams 컴포넌트
<Route path="teams" element={<Teams />}>
// localhost:3000/teams/13 경로 => Team 컴포넌트
<Route path=":teamId" element={<Team />} />
// localhost:3000/teams/new 경로
<Route path="new" element={<NewTeamForm />} />
// localhost:3000/teams 경로 => LeagueStandings 컴포넌트
<Route index element={<LeagueStandings />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
Outlet
부모 경로 요소에서 자식 경로 요소를 렌더링하기 위해 사용함
하위 경로가 렌더링될 때 중첩된 UI가 표시될 수 있음
부모 라우트가 일치할 경우 자식 인덱스 라우트를 렌더링 함
만약 인덱스 라우트가 없으면 아무것도 렌더링하지 않음
// 부모 경로 요소 App 컴포넌트
function App() {
return (
<div>
<div className="content">
// 자식 경로 요소
<Outlet />
</div>
</div>
);
}
// 루트 라우트의 자식 라우트
// Outlet === 자식 경로 요소
<Route index element={<Home />}>
<Route path="teams" element={<Teams />}>
<Route path=":teamId" element={<Team />} />
<Route path="new" element={<NewTeamForm />} />
<Route index element={<LeagueStandings />} />
</Route>
</Route>
// 루트 경로 접근 시 렌더링
<App>
<Home /> // 인덱스 라우트
</App>
// /teams 경로 접근 시 렌더링
<App>
<Teams>
<LeagueStandings /> // 인덱스 라우트
</Teams>
</App>
// /teams/new 경로 접근 시 렌더링
<App>
<Teams>
<NewTeamForm />
</Teams>
</App>
useNavigate
경로를 변경해 줌
navigate('/home') => localhost:3000/home
// localhost:3000/home
navigate('/home', { replace: true });
replace: true
해당 주소로 넘어간 후 뒤로 가기를 하더라도
방금의 페이지로 돌아오지 않고 메인 페이지 ('/') 로 돌아옴
replace: false
뒤로 가기 가능 (기본 값)
useParams
path 경로에 :style 문법을 사용했을 경우
useParams() 로 해당 값을 가져올 수 있음
import { Routes, Route, useParams } form 'react-router-dom';
function App() {
return (
<Routes>
<Route
path='products/:productId'
element={<Product />}
/>
</Routes>
);
}
function Product() {
// path 에서 params을 가져옴
let params = useParams();
// params 에서 이름으로 값을 찾음
return <h1>Product {params.productId}</h1>;
}
useLocation
현재 URL 정보를 가져올 수 있음
useLocation Hooks는 현재 위치 객체를 반환함
const location = useLocation();
console.log(location);
// {
// pathname: 'products/food/',
// search: '?fruits',
// hash: '',
// state: undefined
// }
useRoutes
<Routes> 와 기능적으로 동일함
<Route> 요소 대신 JavaScript 객체를 사용해 경로를 정의함
이 객체는 <Route> 요소와 동일한 속성을 갖지만 JSX가 필요하지 않음
import * as React from 'react';
import { useRoutes } from 'react-router-dom';
function App() {
let element = useRoutes([
{
path: '/',
element: <DashBoard />,
children: [
{
path: 'messages',
element: <DashBoardMessage />
},
{ path: 'tasks', element: <DashBoardTasks /> }
]
},
{ path: 'team', element: <AboutPage /> }
]);
return element;
}
Link 구성 요소
to 속성을 이용해 이동할 경로를 지정함
링크 클릭 시 해당 경로 이름과 매치되는 구성 요소를 렌더링함
<Link to='about'>About 페이지 보여주기</Link>