3월 5일 자 학습 내용 정리입니다.
✅ react-router
react-router는 컴포넌트를 특정 path와 연결하고 해당 path로 진입 시 연결된 컴포넌트를 렌더링 하게 한다.
query, path variable 등 URL parameter를 얻어 활용하며 조건에 맞지 않을 경우 redirect 한다.
현재 react는 17.0.2 버전이 나와있는데 16.8 버전부터 React Router가 v6로 업그레이드됐다.
이전 v5와는 다른 문법들이 많이 존재하기 때문에 이 점을 유의할 필요가 있다.
react-router v6의 설치 명령어는 아래와 같다.
$ npm install react-router-dom@6
$ yarn add react-router-dom@6
react-router v6의 구성요소는 크게 BrowserRouter, Routes, Route, Link로 이루어진다.
각 구성요소를 살펴보기 전에 routes 코드를 살펴보면 다음과 같다.
import { render } from "react-dom";
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<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>
</Routes>
</BrowserRouter>,
document.getElementById("root")
);
제일 상위에는 BrowserRouter가 존재한다.
그리고 그 아래 Routes가 있고 Routes안에 Route들이 존재한다.
각 Route들은 path, element 등을 가지고 있으며 해당하는 path로 접근 시 element의 컴포넌트를 렌더링 한다.
✔️ BrowserRouter
프로젝트에 라우터를 적용하기 위해서는 BrowserRouter 컴포넌트로 라우터들을 감싸주는 작업이 필요하다.
BrowserRouter는 HTML5의 History API를 이용해 페이지를 새로 불러오지 않고도 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에 전달해 사용할 수 있도록 한다.
✔️ Route
Route는 Routes 컴포넌트 내부에서 사용되며 path와 렌더링 할 컴포넌트가 주어진다.
path는 상대 경로이며 렌더링 할 컴포넌트는 element 안에 들어간다.
<Route path="주소" element={렌더링할 컴포넌트} />
path에 여러 라우팅을 매칭 하고 싶을 경우 URL 뒤에 *을 붙인다.
<Route path="주소/*" element={렌더링할 컴포넌트} />
Route가 중첩되어있을 경우 상위 라우트에 대한 하위 경로를 지정한다.
<Route path="teams" element={<Teams />}>
<Route path=":teamId" element={<Team />} />
<Route path="new" element={<NewTeamForm />} />
<Route index element={<LeagueStandings />} />
</Route>
즉, 이 경우 path=":teamId"
는 path="teams/:teamId"
와 매칭 되며 path="new"
는 path="/teams/new"
와 매칭 된다.
이렇게 제공된 URL 매개변수들은 useParams()
를 이용해 가져올 수 있다.
import { Routes, Route, useParams } from "react-router-dom";
function App() {
return (
<Routes>
<Route
path="invoices/:invoiceId"
element={<Invoice />}
/>
</Routes>
);
}
function Invoice() {
let params = useParams();
return <h1>Invoice {params.invoiceId}</h1>;
}
이외에도 path를 가져오기 위해서는 useLocation()
을 사용할 수 있다.
import { Routes, Route, useLocation } from "react-router-dom";
function App() {
return (
<Routes>
<Route
path="invoices/:invoiceId"
element={<Invoice />}
/>
</Routes>
);
}
function Invoice() {
let location = useLocation();
return <h1>{location.pathname}</h1>;
}
useLocation이 반환하는 값은 현재 사용자가 보고 있는 페이지의 정보를 가지고 있는 객체이다.
이 객체에는 다음과 같은 값이 존재한다.
- pathname : 현재 주소의 경로(query string 제외)
- search : 맨 앞의 ? 문자를 포함한 query string 값
- hash : 주소의 # 문자열 뒤의 값
- state : 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
- key : useLocation()이 반환하는 객체의 고유 값. 초기에는 default를 가지지만 페이지 변경 시 고유 값이 생성됨.
✔️ Link
Link는 일반적으로 쓰이는 a 태그와 비슷하게 페이지를 이동하는 작업을 한다.
하지만 a 태그는 클릭해 페이지를 이동할 때 브라우저에서 페이지를 새로 불러오게 되지만 Link는 페이지를 새로 불러오는 것을 막고 History API를 통해 브라우저 주소의 경로만 바꾼다.
<Link to="경로">링크 이름</Link>
만약 Link 컴포넌트 없이 다른 페이지로 이동을 해야 한다면 useNavigate()를 사용한다.
import { Outlet, useNavigate } from 'react-router-dom';
const Layout = () => {
const navigate = useNavigate();
const goBack = () => {
// 이전 페이지로 이동
navigate(-1);
};
const goArticles = () => {
// articles 경로로 이동
navigate('/articles');
};
return (
<div>
<header>
<button onClick={goBack}>뒤로가기</button>
<button onClick={goArticles}>게시글 목록</button>
</header>
<main>
<Outlet />
</main>
</div>
);
};
useNavigate()의 파라미터가 주소라면 해당하는 주소로 이동한다.
반면 useNavigate()의 파라미터가 숫자 타입이면 해당하는 만큼 앞으로 가거나 뒤로 이동한다.
숫자가 양수라면 앞으로 n번, 음수라면 뒤로 n번 이동하는 식이다.
🔍 참조
react-router-dom v6 overview https://reactrouter.com/docs/en/v6/getting-started/overview
upgrade to react router v6 https://reactrouter.com/docs/en/v6/upgrading/v5#upgrade-to-react-router-v6
react-router-dom v6 https://velog.io/@velopert/react-router-v6-tutorial
react-router-dom v6 https://velog.io/@soryeongk/ReactRouterDomV6
'엘리스 AI 트랙 4기 > elice AI track' 카테고리의 다른 글
[8주차] 상태 관리와 Flux Pattern (0) | 2022.03.11 |
---|---|
[8주차] CORS (0) | 2022.03.09 |
[7주차] React 생명주기 (0) | 2022.03.04 |
[7주차] Hooks (0) | 2022.03.04 |
[7주차] React에서의 이벤트 (0) | 2022.03.04 |
댓글