사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것
여러 페이지로 구성된 웹 애플리케이션을 만들 때 페이지 별로 컴포넌트들을 분리해가면서 프로젝트를 관리하기 위해 필요한 것 ➡️ 라우팅
리액트에서 가장 많이 쓰는 라우팅 라이브러리는 리액트 라우터(React Router)이다.
$ yarn create react-app [프로젝트명]
[프로젝트명]에는 자신이 만들고자 하는 프로젝트의 이름을 넣어 CRA 프로젝트를 생성한다.
$ cd [프로젝트명]
$ yarn add react-router-dom
터미널에 yarn add react-router-dom
명령어를 입력하면 리액트 라우터 라이브러리가 설치된다!
생성한 CRA 프로젝트 파일의 src/index.js
파일에서 react-router-dom
에 내장되어 있는 BrowserRouter
라는 컴포넌트를 사용해서 감싸야한다.
BrowserRouter?
- react-router-dom 컴포넌트를 감싸는 최상단에 위치한다.
- HTML5를 지원하는 브라우저의 주소를 감지한다.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
사용자의 브라우저 주소 경로에 따라 우리가 원하는 컴포넌트를 보여주기 위해 Route
라는 컴포넌트를 통해 라우트 설정을 해주어야 한다.
<Route path="경로" element={보여줄 컴포넌트 JSX} />
Routes
컴포넌트는 여러 Route
를 감싸서 그 중 규칙이 일치하는 라우트 단 하나만을 렌더링시킨다.Route
컴포넌트는 Routes
컴포넌트 내부에서 사용되어야 한다.path
속성에는 경로를, element
속성에는 보여줄 컴포넌트를 넣는다. (여러 라우팅을 매칭하고 싶은 경우에는 url 뒤에 *을 사용한다.App.js
import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Home from './pages/Home';
const App = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
};
export default App;
현재 Home
이라는 컴포넌트와 About
컴포넌트의 라우트 설정을 한 상태이다.
yarn start
명령어를 입력했을 때, 첫 화면에는 Home
컴포넌트가 나타날 것이고, 주소에 /about
을 붙인 후 접속하면 About
컴포넌트가 나타날것이다.
Link
컴포넌트를 사용하면 다른 페이지로 이동할 수 있다.
<Link to="경로">링크 이름</Link>
src/pages/Home.js
import { Link } from 'react-router-dom';
const Home = () => {
...
<Link to="/about">About 페이지로 이동</Link>
};
export default Home;
Home
페이지에 뜨는 "About 페이지로 이동"
을 클릭하면 About
페이지로 이동한다.
+) json 파일에 경로를 저장해두고 props
로 받아와서 사용도 가능하다.
페이지의 주소를 정의하면서 유동적인 값을 사용해야 할 때 사용한다.
import { useParams } from 'react-router-dom';
...
const {파라미터명} = useParams();
주로 URL파라미터는 id값 또는 이름을 사용하여 특정 데이터를 조회할 때 사용한다.
useParams
라는 훅을 사용하여 객체 형태로 조회할 수 있다.
src/pages/Profile.js
import { useParams } from 'react-router-dom';
const data = {
readysetq: {
name: 'readysetq',
description: '리액트를 공부하는 아기사자',
},
gildong: {
name: '홍길동',
description: '고전 소설 홍길동전의 주인공',
},
};
const Profile = () => {
const params = useParams();
const profile = data[params.username];
return (
<div>
<h1>사용자 프로필</h1>
{profile ? (
<div>
<h2>{profile.name}</h2>
<p>{profile.description}</p>
</div>
) : (
<p>존재하지 않는 프로필입니다.</p>
)}
</div>
);
};
export default Profile;
App.js
import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Home from './pages/Home';
import Profile from './pages/Profile';
const App = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/profiles/:username" element={<Profile />} />
</Routes>
);
};
export default App;
url 파라미터의 이름은 라우트 설정할 때 Route
컴포넌트의 path
props를 통해 설정한다.
url 파라미터는 경로에 :
를 사용하여 설정한다.
쿼리스트링은 키워드 검색, 페이지네이션, 정렬방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용한다.
주소의 뒷부분에 ?
문자열 이후 key=value 로 값을 정의하며 &
로 구분하는 형태이다.
현재 사용자가 보고 있는 페이지의 정보를 지니고 있는 객체를 반환하는 useLocation
훅을 사용한다.
location
객체의 고유 값. 초기값은 default이며 페이지가 변경될 때마다 고유의 값이 생성된다.src/pages/About.js
import { useLocation } from 'react-router-dom';
const About = () => {
const location = useLocation();
return (
<div>
<h1>소개</h1>
<p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
<p>쿼리스트링: {location.search}</p>
</div>
);
};
export default About;
{location.search}
이외에도 {location.hash}
, {location.state}
등 원하는 정보를 조회할 수 있다.
리액트 라우터에서는 v6부터 useSearchParams
라는 훅을 사용하여 쿼리스트링을 피싱하여 사용할 수 있다.
import { useSearchParams } from 'react-router-dom';
const About = () => {
// [쿼리파라미터 조회/수정 메서드, 쿼리파라미터 업데이트 함수]
const [searchParams, setSearchParams] = useSearchParams();
const detail = searchParams.get('detail');
const mode = searchParams.get('mode');
const onToggleDetail = () => {
setSearchParams({ mode, detail: detail === 'true' ? false : true });
};
const onIncreaseMode = () => {
const nextMode = mode === null ? 1 : parseInt(mode) + 1;
setSearchParams({ mode: nextMode, detail });
};
return (
<div>
<h1>소개</h1>
<p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
<p>detail: {detail}</p>
<p>mode: {mode}</p>
<button onClick={onToggleDetail}>Toggle detail</button>
<button onClick={onIncreaseMode}>mode + 1</button>
</div>
);
};
export default About;
주의해야 할 점은 쿼리파라미터를 조회할 때 값은 무조건 문자열 타입이다!
true/false 값을 넣을 때 따옴표로 감싸야 하고, 숫자를 다루게 된다면 parseInt
를 사용하여 숫자 타입으로 변환해야한다.
Link 컴포넌트를 사용하지 않고 다른 페이지로 이동할 때 (뒤로가기 등) 사용하는 훅이다.
replace 옵션을 사용하면 페이지를 이동할 때 히스토리를 남기지 않는다.
import { useNavigate } from 'react-router-dom';
...
const Layout = () => { // Layout이라는 컴포넌트
const navigate = useNavigate();
const goBack = () => { // 이전페이지로 이동
navigate(-1);
};
const goArticles = () => { // articles 경로로 이동
navigate('/articles', { replace: true });
};
...
return (
<>
<button onClick={goBack}>뒤로가기</button>
<button onClick={goArticles}>게시글 목록</button>
</>
);
};
navigate(-1)
은 한번 뒤로 가라는 의미, useNavigate
훅을 사용해서 뒤로가기 버튼을 만들었다.
{ replace: true }
를 통해 replace 옵션을 활성화하여 페이지를 이동할 때 현재 페이지를 페이지 기록에 남기지 않도록 했다.!