라우팅은 웹 애플리케이션에서 사용자가 요청한 URL에 따라
적절한 컴포넌트나 페이지를 보여주는 것을 말합니다.
웹 애플리케이션은 일반적으로 여러 개의 페이지나 화면으로 구성되어 있습니다.
브라우저의 URL이 변경될 때마다, 해당 URL에 맞는 컴포넌트를 로드하고 보여주는 것이 라우팅의 역할입니다.
쉽게 이야기 하자면, 다양한 주소의 요청이 들어왔을 때 각각 맞는 콘텐츠로 이동시켜 주는 작업이라고 볼 수 있습니다.
마치 우체국에서 편지를 집 주소에 맞게 배달하는 것처럼 말이죠.
React router dom
<a> Tag 가 있는데 왜 굳이 react-router-dom 을 사용하는 것일까요??
React 의 주요 장점 중 하나는 단일 페이지 애플리케이션(SPA) 입니다.
SPA 는 한번에 하나의 HTML 페이지만 로드되고, 페이지 간의 전환은 JavaScript 를 사용하여 동적으로 이루어집니다.
일반적으로 SPA 에서 <a> Tag 를 사용하면 브라우저가 새로운 페이지를 로드하려고 시도하고 전체 페이지를 다시 렌더링 합니다.
이는 SPA 의 핵심인 페이지 간의 부드러운 전환과 상태의 유지를 위배하는 것입니다.
react-router-dom 은 새로운 URL에 따라 해당하는 컴포넌트를 렌더링하고, 전체 페이지를 새로고침하지 않고도 UI를 업데이트할 수 있습니다.
그럼 본격적으로 정리해 보도록 하겠습니다.
설치
npm install react-router-dom
시작하기
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from "./pages/Home.jsx"
import About from "./pages/About.jsx"
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element = {<Home />} />
<Route path="/about" element = {<About />}>
</Routes>
</BrowserRouter>
);
};
이렇게 설정하면 " / " 경로로 갔을 때 Home Component 가 렌더링 되고 " /about " 경로로 갔을 때 About Component 가 렌더링 됩니다.
BrowserRouter
- history API를 활용해 history 객체를 생성한다.
- history API는 내부적으로 stack 자료구조의 형태를 띄기 때문에 사용자가 방문한 url 기록들을 차곡차곡 쌓는 형태로 저장해둔다고 생각하면 된다.
- 라우팅을 진행할 컴포넌트 상위에 BrowserRouter 컴포넌트를 생성하고 감싸주어야 한다.
Route
- 현재 브라우저의 location(window.href.location 정보를 가져온다) 상태에 따라 다른 element를 렌더링한다.
- Route.element: 조건이 맞을 때 렌더링할 element, <Element />의 형식으로 전달된다.
- Route.path: 현재 path값이 url과 일치하는지 확인해 해당 url에 매칭된 element를 렌더링해준다.
Routes
- 모든 Route의 상위 경로에 존재해야 하며, location 변경 시 하위에 있는 모든 Route를 조회해 현재 location과 맞는 Route를 찾아준다.
Link
Link 컴포넌트는 라우터 내에서 직접적으로 페이지 이동을 하고자 할 때 사용되는 컴포넌트입니다.
만약 Navbar 을 만들고 있다면 Link 를 이용해서 경로를 설정해 주면 됩니다.
import React from 'react';
import {Link} from 'react-router-dom';
function Nav(){
return (
<div>
<Link to='/'> Home </Link>
<Link to='/about'> About </Link>
</div>
);
}
export default Nav;
Link 를 이용하면 위에서 설명한 <Route path="/" element={<Home />} /> 에서
path 경로에 따라 해당 컴포넌트로 이동할 수 있습니다.
useNavigate
만약 어떤 특정 이벤트가 발생하면 home 이라는 page 로 이동하고 싶다면 어떻게 해야 할까요? Link 를 사용해야 할까요?
특정 이벤트가 발생했을 때 특정 경로로 이동하고 싶다면 useNavigate 를 사용하시면 됩니다.
import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
const onClick = () => navigate('/')
return ( <button onClick={onClick}> Home 으로 가기 </button>)
...
button 을 클릭하게 되면 path="/" 로 설정한 Home component 로 이동하게 됩니다.
useNavigate 는 다음과 같은 속성도 추가할 수 있습니다.
// 첫번째
navigate("/", { replace: true });
// 두번째
navigate("/", { state: { cardId: cardId } });
// 다른 페이지에서 사용
const location = useLocation();
const { cardId } = location.state;
navigate 의 두번째 인자로 객체 형태가 들어가는데
replace 는 기본값은 false이고, true로 설정한다면 이동 후 뒤로가기가 불가능해집니다.
state 는 특정 값을 해당 페이지로 넘겨서 사용할 수 있습니다.
useParams
URI 파라미터를 이용하고 싶을때 사용합니다.
이렇게만 말하면 감을 못잡을 수도 있기 때문에 코드로 보여드리겠습니다.
만약 http://localhost/users/1 이라는 주소로 들어간다고 생각했을때 1이라는 파라미터를 가져올 수 있습니다.
import React from 'react';
import { useParams } from 'react-router-dom';
const UserId = () => {
let { id } = useParams();
return (
<div>
<p>현재 유저의 아이디는 { id } 입니다.</p>
</div>
)
}
export default UserId;
이렇게 설정하면 <Route path="" element={<UserId/>}/> 에서 path 가 궁금하실 것입니다.
path = "/users/:id" 라고 정의해주면 사용이 가능합니다.
즉 :id 라는 곳이 1 이라는 뜻이고 그걸 useParams 로 가져 올 수 있습니다.
중첩 라우트
중첩 라우트는 Route 안에 Route 를 포함하는 말입니다.
간단하게 설명하자면 공통된 Navbar 을 하위 Route 들에서 사용하고 싶을 때 이용할 수 있습니다.
<Route path="/about" element={<About />}>
<Route path="location" element={<Location />}></Route>
</Route>
이러한 코드가 있을 때 /about 이라는 경로와 /about/location 이라는 경로가 생성됩니다.
위와 같이 설정한 것 만으로는 아무런 변화가 생기지 않습니다. 실제로 해당 라우팅이 발생하는 부모 요소인 About 페이지에 하위 라우팅 발생 시 컴포넌트를 렌더링 할 자리를 명시해 주어야 합니다.
어떤 이야기 인지 모를 수 있기 때문에 코드와 그림으로 설명하겠습니다.
import { Outlet } from 'react-router-dom';
function About() {
return (
<div>
<h2>여기는 About 페이지입니다.</h2>
<Outlet /> <-- <Location/> 이 들어갈 자리입니다.
</div>
);
}
코드를 보면 Outlet 이라는 Tag 가 있습니다.
즉 About component 에 정의한 태그들과 스타일들을 사용하면서 <Outlet/> 부분에 위에서 설명한 Location coponent 가
들어갑니다. 이 중첩 라우트를 사용하는 경우는 공통된 Navbar 을 보여주고 싶거나, 공통된 이미지나, 스타일을 적용해야 할때 사용됩니다.
밑에 예시처럼 Navbar 은 공통으로 사용하고 밑에 보여지는 부분은 내용이 다를때 사용하면 이해하기 쉽습니다.
쿼리스트링
쿼리 스트링을 사용하면 조건에 맞게 정렬된 특정 형태의 정보를 요청하고 받을 수 있습니다.
즉 쇼핑몰을 예로 들자면 특정 옷이나, 바지, 아우터만 골라서 데이터를 가져올 때 유용하게 사용할 수 있습니다.
만약 모든 옷을 가져와서 바지, 아우터만 고르면 서버에 부담도 크고 클라이언트에서도 방대한 데이터를 불어와야 하기
때문에 빈 화면을 사용자에게 보여줄 수도 있습니다.
쿼리 스트링은 문자열의 형태를 띄며 key=value 로 표현합니다.
URL 의 일부이므로 ? 를 통해 여기부터 시작이라고 표시해야 하고, 각 페어의 구분은 & 로 합니다
// 인기순으로 정렬된 정보 >>> https://www.example.com/products?sort=popular
여기서 key 는 sort 이며, value 는 popular 입니다.
react-router-dom 에서 쿼리스트링을 이용한 주소는 아래 코드처럼 만들어 주면 됩니다.
주로 쿼리스트링은 sort = ${ } 처럼 동적으로 넣어주는 방법을 많이 사용합니다.
// Link 컴포넌트
<Link to="/list?sort=popular" />
// useNavigate
navigate("/list?sort=popular")
react-router-dom 에서 쿼리 스트링 값을 가져올 수 있는 hook 으로는 useLocation, useSearchParams 두개가 있습니다.
대부분 useSearchParams 를 사용하기 때문에 useSearchParams 만 설명하겠습니다.
만약 useLocation 이 궁금하다면 공식문서를 참고해 주세요. ( 자주 안쓰는 이유가 있을 것입니다 ㅎㅎ )
useSearchParams 의 기본 사용법은 아래와 같습니다.
const [serchParams, setSearchParams] = useSearchParams();
searchParams 는 쿼리 스트링을 다루기 위한 여러 메서드를 제공합니다.
setSearchParams 는 현재 URL 의 쿼리 스트링을 변경하는 기능을 제공합니다.
값을 읽어오는 메서드
- searchParams.get(key) - 특정한 key 의 value 를 가져오는 메서드입니다.
- searchParams.getAll(key) - 특정 key 에 해당하는 모든 value 를 가져오는 메서드 입니다.
- searchParams.toString() - 쿼리 스트링을 string 형태로 return 해 줍니다.
값을 변경하는 메서드
- searchParams.set(key,value) - 인자로 전달한 key 값을 value 로 설정
- searchParams.append(key, value) - 기존 값을 변경하거나 삭제하지 않고 추가하는 방식
만약 users?age=21&jop=developer 이라는 쿼리 스트링이 있다면 어떤 식으로 가져올 수 있을까요??
// 처음 유저가 /user?age=21&jop=developer 이렇게 접속한다고 가정
const List = () => {
const [searchParams, setSearchParams] = useSearchParams();
const age = searchParams.get('age');
const jop = searchParams.get('jop');
return (
<section>
<h1>chans age is {age} , jop is {jop}</h1>
</section>
);
};
대부분은 쿼리 스트링을 데이터를 불러올 때 많이 사용합니다.
만약 데이터가 page= 1 , 2, 3... 순으로 저장되어 있고 특정 버튼을 클릭할때 마다 새로운 데이터를 불러오고 싶다면
아래의 코드처럼 만드는 경우가 대부분 일것입니다.
예를 들어서 짠 형태라 생략된 부분이 많습니다.
const [searchParams, setSearchParams] = useSearchParams()
const page = searchParams.get('page');
useEffect(()=> {
const response = axios.get("https://test.com/page={page}")
....
}, [])
const movePage = (pageNumber) => {
searchParams.set('page', pageNumber);
setSearchParams(searchParams);
};
return (
<div>
<button onClick={() => movePage(1)}>1</button>
<button onClick={() => movePage(2)}>2</button>
<button onClick={() => movePage(3)}>3</button>
</div>
)
기본적인 부분은 여기까지 입니다.
여기까지 배우고 적용하셨다면 React-router-dom 을 사용하는데 문제없이 프로젝트에 적용하고 사용할 수 있을 것입니다.
이 외에도 공식 문서를 보면 다양한 기능이 있지만 제가 개발했을 때 저정도만 알아도 충분히 프로젝트를 개발하는데
어려움이 없었기 때문에 이정도만 정리해 보도록 하겠습니다.
'라이브러리' 카테고리의 다른 글
browser-image-compression (0) | 2024.07.15 |
---|---|
React 에서 emtion 사용하기 (0) | 2024.07.09 |
React 에서 gsap 사용하기 (0) | 2024.07.03 |
React 에서 AOS 사용하는 방법 (0) | 2024.05.18 |
Styled-components (1) | 2024.05.01 |