6. [React] 6. React Router (리액트 라우터) 사용하기
이번 포스팅은 [ React에서 페이지 이동 처리 하는 방법 ] 입니다. : )
우리가 흔히 말하는 "페이지 이동"이라는 기능을 리액트에서는 리액트 라우터를 통해 처리할 수 있다.
라우팅이 무엇인지 간단하게 살펴보자.
1. 라우팅이란?
- 간단하게 생각 하자면 사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것이라고 생각할 수 있다.
- 리액트에서는 라우팅 관련 라이브러리가 많이 있는데, 이중 가장 많이 쓰이는 리액트 라우터(React Router)를 사용해보려 한다.
※ SPA, SSR, SSG 등의 대한 개념을 어느정도 갖춘 상태에서 다음 내용을 진행하는것을 추천 한다.
리액트는 SPA (Single Page Application) 방식
- 기존 웹 페이지 처럼(MPA 방식) 여러개의 페이지를 사용, 새로운 페이지를 로드하는 방식이 아니다.
- 새로운 페이지를 로드하지 않고 하나의 페이지 안에서 필요한 데이터만 가져오는 형태를 가진다.
React-Router는 신규 페이지를 불러오지 않는 상황에서 각각의 url에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리 라고 볼 수 있다.
2. 리액트 라우터(React Router)
- 사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종유의 라우터 컴포넌트를 제공한다.
- 이중 가장 많이 사용하는 라우터 컴포넌트는 BrowserRouter와 HashRouter이다.
1) 종류
- BrowserRouter : HTML5를 지원하는 브라우저의 주소를 감지 한다.
- HashRouter 해시 주소(http://goddaehee.tistory.com/#test )를 감지 한다.
※ 참고
현재 이 글을 작성하고 있는 시점 기준으로 최신 버전은 v6이다.
v5와 v6의 문법은 차이가 있으니 v6기준으로만 작성하도록 한다.
v5=>v6 migration 하는 가이드
https://reactrouter.com/docs/en/v6/upgrading/v5#upgrading-from-v5
2) 설치
- npm
npm install react-router-dom
- yarn
yarn add react-router-dom
3) 사용 예시
- 라우터를 사용하기 전에 먼저 쇼핑몰이라고 가정하여 샘플 페이지를 만들어 보자.
(App, 헤더, 메인 페이지, 상품 상세 페이지)
ex) App.js
import React, { Component } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './Header';
import Main from './Main';
import Product from './Product';
const App = () => {
return (
<div className='App'>
<Header />
<Main />
<Product />
</div>
);
}
export default App;
ex) Header.js
import React from 'react';
function Header(props) {
return (
<>
<h1>헤더입니다.</h1>
</>
);
}
export default Header;
ex) Main.js
import React from 'react';
const Main = (props) => {
return (
<>
<h3>안녕하세요. 메인페이지 입니다.</h3>
</>
);
};
export default Main;
ex) Product.js
import React from 'react';
const Product = (props) => {
return (
<>
<h3>상품 페이지입니다.</h3>
</>
);
}
export default Product;
- 렌더링 결과
현재는 헤더, 메인페이지, 상품상세 페이지가 같이 보인다.
이제부터 Router를 활용 해보자
1. <BrowserRouter>태그로 컴포넌트 사용하기
- BrowserRouter를 사용 할 것이기 떄문에, <BrowserRouter>태그로 컴포넌트를 감싸주자.
- Header는 모든 URL에 공통 적용할 Component로 최상단에 위치 할 예정이다.
2. <Routes>, <Route> 컴포넌트 사용하기
- <Routes>컴포넌트는 여러 Route를 감싸서 그 중 규칙이 일치하는 라우트 단 하나만을 렌더링 시켜주는 역할을 한다.
- <Route>는 path속성에 경로, element속성에는 컴포넌트를 넣어 준다. 여러 라우팅을 매칭하고 싶은 경우 URL 뒤에 *을 사용하면 된다.
2.1) "/"로 접근시 메인페이지(Main.js)를 보여줄 것이다.
2.2) "/product/상품번호"로 접근시 상품상세페이지(Product.js)를 보여 줄 것이다.
3. <Link> 컴포넌트 사용하기
- 웹 페이지에서는 원래 링크를 보여줄 때 a태그를 사용한다. 하지만 a태그는 클릭시 페이지를 새로 불러오기때문에 사용하지 않는다.
- Link 컴포넌트를 사용하는데, 생김새는 a태그를 사용하지만, History API를 통해 브라우저 주소의 경로만 바꾸는 기능이 내장되어 있다.
- 문법 : <Link to="경로">링크명</Link>
- import { Link } from 'react-router-dom';
4. 사전에 정의하지 않은 경로로 접근하는 경우 NotFound 페이지로 이동 처리
ex) App.js - BrowserRouter를 사용해 보자.
import React, { Component } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './Header';
import Main from './Main';
import Product from './Product';
import NotFound from './NotFound';
const App = () => {
return (
<div className='App'>
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<Main />}></Route>
<Route path="/product/*" element={<Product />}></Route>
{/* 상단에 위치하는 라우트들의 규칙을 모두 확인, 일치하는 라우트가 없는경우 처리 */}
<Route path="*" element={<NotFound />}></Route>
</Routes>
</BrowserRouter>
</div>
);
};
export default App;
ex) Main.js - Main모듈에 특정 상품 상세 페이지로 이동하는 링크를 추가하여 주자.
import React from 'react';
import { Link } from 'react-router-dom';
const Main = (props) => {
return (
<>
<h3>안녕하세요. 메인페이지 입니다.</h3>
<ul>
<Link to="/product/1"><li>1번상품</li></Link>
<Link to="/product/2"><li>2번상품</li></Link>
</ul>
</>
);
};
export default Main;
ex) Header.js - "헤더입니다."를 클릭시 "/"페이지로 이동할 수 있게 링크를 추가 하자.
import React from 'react';
import { Link } from 'react-router-dom';
function Header(props) {
return (
<>
<Link to="/">
<h1>헤더입니다.</h1>
</Link>
</>
);
}
export default Header;
ex) NotFound.js
import React from 'react';
const NotFound = () => {
return (
<div>
404 Error
</div>
);
};
export default NotFound;
※ 4개의 모듈을 모두 작성한 후 다음과 같이 접속 하면 페이지 분기 처리되는것을 볼 수 있다.
case1) 루트경로 접속시 (/)
<Route path="/" element={<Main />}></Route>
case2) 상품상세 페이지 접속시 (/product/*)
<Route path="/product/*" element={<Product />}></Route>
- 아직까진 1번 상품, 2번 상품과 상관없이 동일한 상품 페이지가 노출된다.
case3) 정의하지 않은 경로 접속시 (/kkkkkk)
<Route path="*" element={<NotFound />}></Route>
5. URL 파라미터와 쿼리 스트링 사용하기
- 파라미터, 쿼리스트링을 통해 유동적으로 동작할 수 있다.
ex)
URL 파라미터 : /product/1
쿼리스트링 : /product?product=1&searchKeyword=productName
5.1) URL 파라미터
- /product/:productId 와 같이 경로에 : 를 사용하여 설정 한다.
- URL 파라미터가 여러개인 경우엔 /product/:productId/:productName 과 같은 형태로 설정할 수 있다.
- 다음 구문을 사용하는 컴포넌트에 추가하여 사용 가능하다.
import { useParams } from 'react-router-dom';
const { 파라미터명 } = useParams(); // const 변수명 = useParams().파라미터명;
ex) App.js => productId를 파라미터로 받을 수 있게 추가 하자.
import React, { Component } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './Header';
import Main from './Main';
import Product from './Product';
import NotFound from './NotFound';
const App = () => {
return (
<div className='App'>
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<Main />}></Route>
<Route path="/product/:productId" element={<Product />}></Route>
{/* 엘리먼트의 상단에 위치하는 라우트들의 규칙을 모두 확인하고, 일치하는 라우트가 없다면 이 라우트가 화면에 나타나게 됩니다. */}
<Route path="*" element={<NotFound />}></Route>
</Routes>
</BrowserRouter>
</div>
);
};
export default App;
ex) Product.js => useParams를 통해 App.js 에 추가한 productId를 받아 활용 가능하다.
import React from 'react';
import { useParams } from 'react-router-dom';
const Product = () => {
const { productId } = useParams();
return (
<>
<h3>{productId}번 상품 페이지 입니다.</h3>
</>
);
}
export default Product;
※ 파라미터를 통해 상품ID를 활용할 수 있게 되었다.
5.2) 쿼리스트링
- 하기 useLocation, useSearchParams 도 개발시 활용 가능할 것 같아 간단히 정리만 하고 넘어가자.
1) useLocation
- hash : 주소의 #문자열 뒤의 값
- pathname : 현재 주소 경로
- search : ?를 포함한 쿼리스트링
- state : 페이지로 이동시 임의로 넣을 수 있는 상태 값
- key : location 객체의 고유 값, 초기값은 default, 페이지가 변경될 때 마다 고유의 값이 생성된다.
ex) Product
import React from 'react';
import { useParams } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
const Product = () => {
const productId = useParams().productId;
const location = useLocation();
return (
<>
<h3>{productId}번 상품 페이지 입니다.</h3>
<ul>
<li>hash : {location.hash}</li>
<li>pathname : {location.pathname}</li>
<li>search : {location.search}</li>
<li>state : {location.state}</li>
<li>key : {location.key}</li>
</ul>
</>
);
}
export default Product;
- 샘플 url
http://localhost:3000/product/1?search=productName&q=demo#test
2) useSearchParams
ex)
import React from 'react';
import { useParams } from 'react-router-dom';
import { useSearchParams } from 'react-router-dom';
const Product = () => {
const productId = useParams().productId;
const keyWords = searchParams;
const keyWord = searchParams.get("search");
return (
<>
<h3>{productId}번 상품 페이지 입니다.</h3>
<ul>
<li>keyWords : {keyWords}</li>
<li>keyWord : {keyWord}</li>
</ul>
</>
);
}
export default Product;
- 결과 페이지
6. useNavigate
- Link 컴포넌트를 사용하지 않고 다른 페이지로 이동을 해야 하는 경우, 뒤로가기 등에 사용하는 Hook 이다.
- replace 옵션을 사용하면 페이지를 이동할 때 히스토리를 남기지 않는다.
ex)
import React from 'react';
import { useParams } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
const Product = () => {
const productId = useParams().productId;
const navigate = useNavigate();
return (
<>
<h3>{productId}번 상품 페이지 입니다.</h3>
<ul>
<li><button onClick={() => navigate(-2)}>Go 2 pages back</button></li>
<li><button onClick={() => navigate(-1)}>Go back</button></li>
<li><button onClick={() => navigate(1)}>Go forward</button></li>
<li><button onClick={() => navigate(2)}>Go 2 pages forward</button></li>
<li><button onClick={() => navigate('/')}>Go Root</button></li>
<li><button onClick={() => navigate('/', {replace: true})}>Go Root</button></li>
</ul>
</>
);
}
export default Product;
출처 : https://goddaehee.tistory.com/305?category=395445
'javaScript&jQurey > REACT' 카테고리의 다른 글
[React] 7. React hooks[3] - useReducer란? (0) | 2022.10.13 |
---|---|
[React] 7. React hooks[2] - useEffect란? (0) | 2022.10.13 |
[React] 4. React 컴포넌트(5) - map() 반복문, 배열 컴포넌트 (0) | 2022.10.06 |
[React] 4. React 컴포넌트(4) - 이벤트 처리 방법 (4) | 2022.10.05 |
[React] 4. React 컴포넌트(3) - State 알아보기(React Hooks 사용) (0) | 2022.09.28 |