React Router

정홍섭·2023년 8월 9일
0

Frontend

목록 보기
2/2
post-thumbnail

라우팅이란?

  • 사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것
  • 리엑트에서는 라우팅 관련 라이브러리가 많이 있는데, 이 중 가장 많이 쓰이는 리엑트 라우터이다

React는 SPA방식

  • 기존 웹 페이지 처럼 여러개의 페이지를 사용, 새로운 페이지를 로드하는 방식이 아님
  • 새로운 페이지를 로드하지 않고 하나의 페이지 안에서 필요한 데이터만 가져오는 형태를 가짐

React Router란?

  • 사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트를 제공
  • 이중 가장 많이 사용하는 라우터 컴포넌트는 BrowserRouter와 HashRouter이다

종류

Hash Router

  • 주소에 해쉬가 붙는다
  • 검색 엔진이 읽지 못한다
  • 별도의 서버 설정을 하지 않더라도 새로고침 시 오류가 발생하지 않는다

Browser Router

  • History API를 사용한다
  • 별도의 서버 설정을 하지 않으면 새로고침 시 404 에러가 발생한다

리엑트 라우터 적용및 기본 사용법

순서

프로젝트 생성 및 라이브러리 설치

  • yarn
$ yarn install react-router-dom
  • npm
$ npm install react-router-dom

사용예시

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)를 보여 줄 것이다.

  • 웹 페이지에서는 원래 링크를 보여줄 때 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;

NotFound.js

import React from 'react';

const NotFound = () => {
    return (
        <div>
            404 Error
        </div>
    );
};
  
export default NotFound;

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;

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;

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

이렇게 유용한 정보를 공유해주셔서 감사합니다.

답글 달기