웹 어플리케이션에서 라우팅은 사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것을 말한다.
여러 페이지로 구성된 웹 어플리케이션을 만들 때 페이지 별로 컴포넌트들을 분리해가며 프로젝트를 관리하기 위해 필요한 것이 라우팅 시스템이다.
리액트에서 라우트 시스템을 구축하기 위한 선택지는 크게 두 개가 있다.
▶ 리액트 라우터
: 리액트의 라우팅 관련 라이브러리들 중 가장 오래되었고, 가장 많이 사용된다.
: 컴포넌트 기반으로 라우팅 시스템을 설정할 수 있다.
▶ Next.js
: 리액트 프로젝트의 프레임워크
: 리액트 프로젝트 설정 기능, 라우팅 시스템, 최적화, 다국어 시스템 지원, 서버 사이드 렌더링 등 다양한 기능 제공
: 파일 경로 기반으로 작동
: 리액트 라우터의 대안으로 많이 사용
2. 싱글 페이지 어플리케이션이란?
싱글 페이지 어플리케이션이란 하나의 페이지로 이루어진 어플리케이션을 말한다.
< 멀티 페이지 어플리케이션 >
멀티 페이지 어플리케이션에서는 사용자가 다른 페이지로 이동할 때마다 새로운 HTML을 받아오고, 페이지를 로딩할 때마다 서버에서 CSS, JS, 이미지 파일등의 리소스를 전달받아 브라우저 화면에 보여준다.
각 페이지마다 다른 HTML 파일을 제공하거나, 데이터에 따라 유동적인 HTML을 생성하는 템플릿 엔진을 사용하기도 한다.
하지만 사용자 인터렉션이 많고 다양한 정보를 제공하는 웹 어플리케이션에는 적합하지 않은 방식이다.
새로운 페이지를 보여줘야 할 때마다 서버 측에서 모든 준비를 하여, 그만큼 서버의 자원을 사용하고, 트래픽 또한 더 많이 발생할 수 있기 때문이다.
따라서, 리액트와 같은 라이브러리를 사용해 뷰 렌더링을 사용자의 브라우저가 담당하고, 웹 어플리케이션을 브라우저에 불러와 실행시킨 후 사용자와의 인터렉션이 발생하면 필요한 부분만 JS를 사용해 업데이트하는 방식을 사용하게 되었다.
이때, 새로운 데이터가 필요하면 서버 API를 호출해 필요한 데이터만 불러와 사용할 수 있다.
< 싱글 페이지 어플리케이션 >
싱글 페이지 어플리케이션은 HTML을 한번만 받아와 어플리케이션을 실행시킨 후, 필요한 데이터만 화면에 업데이트하는 방식이다.
기술적으로 한 페이지만 존재하지만, 여러 페이지가 존재하는 것처럼 느껴진다.
라우팅 시스템(리액트 라우터 등)은 사용자의 브라우저 주소창의 경로에 따라 알맞은 페이지를 보여준다.
링크를 눌러서 다른 페이지로 이동할 때, 서버의 다른 페이지 HTML을 새로 요청하는 것이 아닌, 브라우저의 History API를 사용해 브라우저의 주소창의 값만 변경하고 기존 페이지에 띄웠던 웹 어플리케이션을 그대로 유지하면서 라우팅 설정에 따라 또 다른 웹 페이지를 보여주게 되는 것이다.
3. 리액트 라우터 적용 및 기본 사용법
< 라이브러리 설치 >
리액트 라우터를 설치하기 위해서는 npm이나 yarn을 이용해 react-router-dom 라이브러리를 설치해야 한다.
npm install react-router-dom
yarn add react-router-dom
< 프로젝트에 라우터 적용 >
프로젝트에 리액트 라우터를 적용하기 위해서 src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여 감싸준다.
BrowerRouter 컴포넌트는 웹 어플리케이션에 HTML5의 History API를 사용해 페이지를 새로 불러오지 않고 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 해준다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
roor.render(
<BrowserRouter>
<App />
<BrowserRouter />
);
< 페이지 컴포넌트 만들기 >
여러 페이지로 구성된 웹 어플리케이션을 만들기 위해 각 페이지에서 사용될 컴포넌트를 만들어야 된다.
가장 먼저 보여지는 Home 페이지 컴포넌트와 웹 사이트 소개 페이지인 About 페이지 컴포넌트를 만들어 보았다.
const Home = () => {
return(
<div>
<h1>Home</h1>
<p>가장 먼저 보여지는 home 페이지</p>
</div>
);
};
export default Home;
const About = () => {
return(
<div>
<h1>introduce</h1>
<p>리액트 라우터 사용 페이지</p>
<p>웹 사이트 소개 페이지</p>
</div>
);
};
export default About;
< Route 컴포넌트로 특정 경로에 원하는 컴포넌트 보여주기 >
브라우저 주소 경로에 따라 원하는 컴포넌트를 보여주어야 한다.
따라서, Route라는 컴포넌트를 통해 라우트 설정을 해줘야 한다.
<Route path = "주소 규칙" element = {보여 줄 컴포넌트 JSX} />
Route 컴포넌트는 위와 같이 사용해야 한다.
또한 Route 컴포넌트는 Routes 컴포넌트 내부에서 사용해야 한다.
App 컴포넌트에서 Route 컴포넌트를 사용하여 라우트를 설정할 수 있다.
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;
< Link 컴포넌트를 사용해 다른 페이지로 이동하는 링크 보여주기 >
Link 컴포넌트를 이용해 다른 페이지로 이동하는 링크를 보여줄 수 있다.
웹 페이지에서 링크를 보여줄 때는 a 태그를 사용하지만, 리액트 라우터를 사용하는 프로젝트에서는 a 태그를 사용하면 안된다. a 태그를 클릭하여 페이지를 이동하면 브라우저에서 새로운 페이지를 불러오기 때문이다.
Link 컴포넌트도 a 태그를 사용은 하지만, 새로운 페이지를 불러오는 것은 막고 History API를 통해 브라우저의 주소 경로만 바꾸는 기능을 제공한다.
<Link to = "경로">링크 이름</Link>
Link 컴포넌트는 다음과 같이 사용하며 앞선 예제의 Home 페이지에서 Link 컴포넌트를 사용하여 Home 페이지에서 About 페이지로 이동할 수 있다.
import { Link } from 'react-router-dom';
const Home = () => {
return(
<div>
<h1>Home</h1>
<p>가장 먼저 보여지는 home 페이지</p>
<Link to = "/about">소개</Link>
</div>
);
};
export default Home;
4. URL 파라미터와 쿼리스트링
▶ URL 파라미터
: /profile/velopart
: 주소의 경로에 유동적인 값을 넣는 형태
: 주로 ID 또는 이름을 사용하여 특정 데이터를 조회할 때 사용
▶ 쿼리스트링
: /article?page=1&keyword=react
: 주소의 뒷부분에 ? 문자열 이후 key=value로 값을 정의하며 &로 구분하는 형태
: 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용
< URL 파라미터 >
URL 파라미터는 useParams라는 Hook을 이용해 객체 형태로 조회할 수 있다,
URL 파라미터의 이름은 라우트 설정을 할 때 Route 컴포넌트의 path props를 통해 설정한다.
URL 파라미터는 경로에 : 를 사용하여 설정하고, 만약 파라미터가 여러 개인 경우 /profiles/:username/:field와 같은 형태로 설정 가능하다.
< 쿼리스트링 >
쿼리스트링은 URL 파라미터와 달리 Route 컴포넌트를 사용해 별도로 설정해야 하는 것이 없다.
앞선 About 페이지 컴포넌트를 useLocation Hook을 사용해 아래와 같이 수정하였다.
import { useLocation } from 'react-router-dom';
const About = () => {
const location = useLocation();
return(
<div>
<h1>introduce</h1>
<p>리액트 라우터 사용 페이지</p>
<p>웹 사이트 소개 페이지</p>
<p>쿼리스트림: {location.search}</p>
</div>
);
};
export default About;
useLocation Hook은 location 객체를 반환해 현재 사용자가 보고 있는 페이지의 정보를 가지고 있다.
pathname: 현재 주소의 경로( 쿼리스트링 제외 )
search: 맨 앞의 ? 문자를 포함한 쿼리스트링 값
hash: 주소의 # 문자열 뒤의 값
state: 페이지를 이동할 때 임의로 넣을 수 있는 상태 값
key: location 객체의 고유값. 초기에는 default이며 페이지가 변경될 때마다 고유 값이 생성
location.search를 통해 얻은 쿼리스트링 값을 ?를 제외하고 &문자열로 분리한 후 key와 value를 파싱하는 작업이 필요하다. 리액트 라우터 v6이후부터 useSearchParams라는 Hook을 통해 쿼리스트링을 쉽게 다룰 수 있다.
useSearchParams는 배열 타입의 값을 반환한다.
▶ 첫 번째 원소: 쿼리파라미터를 조회하거나 수정하는 메서드들이 담긴 객체를 반환
- get 메서드: 특정 쿼리파라미터를 조회
- set 메서드: 특정 쿼리파라미터를 업데이트
조회시 쿼리 파라미터가 존재하지 않으면 null로 조회
▶ 두 번째 원소: 쿼리파라미터를 객체 형태로 업데이트 할 수 있는 함수를 반환
※ 쿼리 파라미터를 조회할 때 값은 무조건 문자열 타입이다.
true, false 값을 넣는다면 'true'와 같이 따옴표로 감싸고, 숫자를 다루면 parseInt를 사용해 숫자 타입으로 변환해야 한다.
5. 중첩된 라우트
리액트 프로젝트를 만들다 보면 어떤 컴포넌트 내부에 다른 컴포넌트를 하단에 보여지게 하거나 여러 컴포넌트에서 동일한 위치에 같은 내용을 보여주어야 할 때가 있다.
이때 리액트 라우터에서 제공하는 Outlet이라는 컴포넌트를 사용해야 한다.
Outlet 컴포넌트는 Route의 children으로 들어가는 JSX 엘리먼트를 보여주는 역할을 한다.
[React JS] 리액트를 다루는 기술 - 리액트 라우터로 SPA 개발하기
1. 라우팅이란?
웹 어플리케이션에서 라우팅은 사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것을 말한다.
여러 페이지로 구성된 웹 어플리케이션을 만들 때 페이지 별로 컴포넌트들을 분리해가며 프로젝트를 관리하기 위해 필요한 것이 라우팅 시스템이다.
리액트에서 라우트 시스템을 구축하기 위한 선택지는 크게 두 개가 있다.
▶ 리액트 라우터
: 리액트의 라우팅 관련 라이브러리들 중 가장 오래되었고, 가장 많이 사용된다.
: 컴포넌트 기반으로 라우팅 시스템을 설정할 수 있다.
▶ Next.js
: 리액트 프로젝트의 프레임워크
: 리액트 프로젝트 설정 기능, 라우팅 시스템, 최적화, 다국어 시스템 지원, 서버 사이드 렌더링 등 다양한 기능 제공
: 파일 경로 기반으로 작동
: 리액트 라우터의 대안으로 많이 사용
2. 싱글 페이지 어플리케이션이란?
싱글 페이지 어플리케이션이란 하나의 페이지로 이루어진 어플리케이션을 말한다.
< 멀티 페이지 어플리케이션 >
멀티 페이지 어플리케이션에서는 사용자가 다른 페이지로 이동할 때마다 새로운 HTML을 받아오고, 페이지를 로딩할 때마다 서버에서 CSS, JS, 이미지 파일등의 리소스를 전달받아 브라우저 화면에 보여준다.
각 페이지마다 다른 HTML 파일을 제공하거나, 데이터에 따라 유동적인 HTML을 생성하는 템플릿 엔진을 사용하기도 한다.
하지만 사용자 인터렉션이 많고 다양한 정보를 제공하는 웹 어플리케이션에는 적합하지 않은 방식이다.
새로운 페이지를 보여줘야 할 때마다 서버 측에서 모든 준비를 하여, 그만큼 서버의 자원을 사용하고, 트래픽 또한 더 많이 발생할 수 있기 때문이다.
따라서, 리액트와 같은 라이브러리를 사용해 뷰 렌더링을 사용자의 브라우저가 담당하고, 웹 어플리케이션을 브라우저에 불러와 실행시킨 후 사용자와의 인터렉션이 발생하면 필요한 부분만 JS를 사용해 업데이트하는 방식을 사용하게 되었다.
이때, 새로운 데이터가 필요하면 서버 API를 호출해 필요한 데이터만 불러와 사용할 수 있다.
< 싱글 페이지 어플리케이션 >
싱글 페이지 어플리케이션은 HTML을 한번만 받아와 어플리케이션을 실행시킨 후, 필요한 데이터만 화면에 업데이트하는 방식이다.
기술적으로 한 페이지만 존재하지만, 여러 페이지가 존재하는 것처럼 느껴진다.
라우팅 시스템(리액트 라우터 등)은 사용자의 브라우저 주소창의 경로에 따라 알맞은 페이지를 보여준다.
링크를 눌러서 다른 페이지로 이동할 때, 서버의 다른 페이지 HTML을 새로 요청하는 것이 아닌, 브라우저의 History API를 사용해 브라우저의 주소창의 값만 변경하고 기존 페이지에 띄웠던 웹 어플리케이션을 그대로 유지하면서 라우팅 설정에 따라 또 다른 웹 페이지를 보여주게 되는 것이다.
3. 리액트 라우터 적용 및 기본 사용법
< 라이브러리 설치 >
리액트 라우터를 설치하기 위해서는 npm이나 yarn을 이용해 react-router-dom 라이브러리를 설치해야 한다.
< 프로젝트에 라우터 적용 >
프로젝트에 리액트 라우터를 적용하기 위해서 src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여 감싸준다.
BrowerRouter 컴포넌트는 웹 어플리케이션에 HTML5의 History API를 사용해 페이지를 새로 불러오지 않고 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 해준다.
< 페이지 컴포넌트 만들기 >
여러 페이지로 구성된 웹 어플리케이션을 만들기 위해 각 페이지에서 사용될 컴포넌트를 만들어야 된다.
가장 먼저 보여지는 Home 페이지 컴포넌트와 웹 사이트 소개 페이지인 About 페이지 컴포넌트를 만들어 보았다.
< Route 컴포넌트로 특정 경로에 원하는 컴포넌트 보여주기 >
브라우저 주소 경로에 따라 원하는 컴포넌트를 보여주어야 한다.
따라서, Route라는 컴포넌트를 통해 라우트 설정을 해줘야 한다.
Route 컴포넌트는 위와 같이 사용해야 한다.
또한 Route 컴포넌트는 Routes 컴포넌트 내부에서 사용해야 한다.
App 컴포넌트에서 Route 컴포넌트를 사용하여 라우트를 설정할 수 있다.
< Link 컴포넌트를 사용해 다른 페이지로 이동하는 링크 보여주기 >
Link 컴포넌트를 이용해 다른 페이지로 이동하는 링크를 보여줄 수 있다.
웹 페이지에서 링크를 보여줄 때는 a 태그를 사용하지만, 리액트 라우터를 사용하는 프로젝트에서는 a 태그를 사용하면 안된다. a 태그를 클릭하여 페이지를 이동하면 브라우저에서 새로운 페이지를 불러오기 때문이다.
Link 컴포넌트도 a 태그를 사용은 하지만, 새로운 페이지를 불러오는 것은 막고 History API를 통해 브라우저의 주소 경로만 바꾸는 기능을 제공한다.
Link 컴포넌트는 다음과 같이 사용하며 앞선 예제의 Home 페이지에서 Link 컴포넌트를 사용하여 Home 페이지에서 About 페이지로 이동할 수 있다.
4. URL 파라미터와 쿼리스트링
▶ URL 파라미터
: /profile/velopart
: 주소의 경로에 유동적인 값을 넣는 형태
: 주로 ID 또는 이름을 사용하여 특정 데이터를 조회할 때 사용
▶ 쿼리스트링
: /article?page=1&keyword=react
: 주소의 뒷부분에 ? 문자열 이후 key=value로 값을 정의하며 &로 구분하는 형태
: 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용
< URL 파라미터 >
URL 파라미터는 useParams라는 Hook을 이용해 객체 형태로 조회할 수 있다,
URL 파라미터의 이름은 라우트 설정을 할 때 Route 컴포넌트의 path props를 통해 설정한다.
URL 파라미터는 경로에 : 를 사용하여 설정하고, 만약 파라미터가 여러 개인 경우 /profiles/:username/:field와 같은 형태로 설정 가능하다.
< 쿼리스트링 >
쿼리스트링은 URL 파라미터와 달리 Route 컴포넌트를 사용해 별도로 설정해야 하는 것이 없다.
앞선 About 페이지 컴포넌트를 useLocation Hook을 사용해 아래와 같이 수정하였다.
useLocation Hook은 location 객체를 반환해 현재 사용자가 보고 있는 페이지의 정보를 가지고 있다.
location.search를 통해 얻은 쿼리스트링 값을 ?를 제외하고 &문자열로 분리한 후 key와 value를 파싱하는 작업이 필요하다. 리액트 라우터 v6이후부터 useSearchParams라는 Hook을 통해 쿼리스트링을 쉽게 다룰 수 있다.
useSearchParams는 배열 타입의 값을 반환한다.
▶ 첫 번째 원소: 쿼리파라미터를 조회하거나 수정하는 메서드들이 담긴 객체를 반환
- get 메서드: 특정 쿼리파라미터를 조회
- set 메서드: 특정 쿼리파라미터를 업데이트
조회시 쿼리 파라미터가 존재하지 않으면 null로 조회
▶ 두 번째 원소: 쿼리파라미터를 객체 형태로 업데이트 할 수 있는 함수를 반환
※ 쿼리 파라미터를 조회할 때 값은 무조건 문자열 타입이다.
true, false 값을 넣는다면 'true'와 같이 따옴표로 감싸고, 숫자를 다루면 parseInt를 사용해 숫자 타입으로 변환해야 한다.
5. 중첩된 라우트
리액트 프로젝트를 만들다 보면 어떤 컴포넌트 내부에 다른 컴포넌트를 하단에 보여지게 하거나 여러 컴포넌트에서 동일한 위치에 같은 내용을 보여주어야 할 때가 있다.
이때 리액트 라우터에서 제공하는 Outlet이라는 컴포넌트를 사용해야 한다.
Outlet 컴포넌트는 Route의 children으로 들어가는 JSX 엘리먼트를 보여주는 역할을 한다.
위 코드의 경우 <Route path = ":id" element = {<Article />} /> 부분이 Outlet 컴포넌트를 통해 보여지게 될 것이다.
Article 컴포넌트를 보면 Outlet 컴포넌트가 사용된 자리에 중첩된 라우트가 보여지게 될 것이다.
중첩된 라우트와 Outlet은 페이지끼리 공통적으로 보여줘야 하는 레이아웃이 있을 때도 유용하게 사용된다.
< index props >
Route 컴포넌트에는 index라는 props가 있다.
props는 path = "/"와 동일하다.
index prop를 사용하면 상위 라우터의 경로와 일치하지만, 그 이후에 경로가 주어지지 않았을 때 보여지는 라우트를 설정할 수 있다.
즉, path = "/"와 동일한 역할을 하며 더 명시적으로 표현하는 방법이다.
6. 리액트 라우터 부가 기능
리액트 라우터는 라우팅 작업을 할 때 사용할 수 있는 여러 API를 제공한다.
< useNavigate >
Link 컴포넌트를 사용하지 않고 다른 페이지로 이동해야 하는 상황에 사용하는 Hook이다.
navigate 함수를 사용할 때 파라미터가 숫자 타입이면 앞으로 가거나 뒤로 간다.
navigate(-1)은 뒤로 한번 가고 navigate(1)은 앞으로 한 번 간다.
navigate에서 다른 페이지로 이동할 때 replace라는 옵션이 있다.
replace 옵션을 사용하면 페이지를 이동할 때 현재 페이지를 페이지 기록에 남기지 않는다.
< NavLink >
NavLink 컴포넌트는 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 스타일, CSS 클래스를 적용하는 컴포넌트이다.
NavLink 컴포넌트의 style과 className은 { isActive: boolean }을 파라미터로 전달받는 함수 타입의 값을 전달한다.
< NotFound 페이지 만들기 >
NotFound 페이지는 사전에 정의되지 않는 경로에 사용자가 진입했을 때 보여주는 페이지이다.
페이지를 찾을 수 없을 때 나타내기 위한 페이이다.
*는 wildcard 문자이다. 즉 아무 텍스트나 매칭한다는 의미이다.
*를 사용하면 라우트 엘리면트의 상단에 위치하는 라우트들의 규칙을 모두 확인하고, 일치하는 라우트가 없으면 NotFound라는 해당 라우트가 화면에 나타나게 하는 것이다.
< Navigate 컴포넌트 >
navigate 컴포넌트는 컴포넌트를 화면에 보여주는 순간 다른 페이지로 이동하고 싶을 때 사용하는 컴포넌트이다.
페이지를 리다이렉트하고 싶을 때 사용한다.
예를 들어, 로그인 페이지에서 로그인을 안했을 때 다시 로그인 페이지를 보여주어야 하는 상황에서 사용한다.
'Front-End > React JS' 카테고리의 다른 글