리액트는 사용자 인터페이스를 구축하기 위한 강력한 라이브러리입니다. 그중에서도 React Router는 리액트 애플리케이션에서 클라이언트 측 라우팅을 관리할 수 있는 훌륭한 도구입니다. 이를 통해 사용자가 서로 다른 URL을 통해 다양한 페이지를 탐색할 수 있도록 도와줍니다. 이 글에서는 React Router의 기본 개념과 동적 라우팅 및 URL 파라미터 처리 방법에 대해 자세히 살펴보겠습니다.
1. React Router 소개
React Router는 리액트 애플리케이션에 “페이지”를 추가하는 데 필요한 도구를 제공합니다. 기본적으로 React Router는 URL과 그에 따라서 렌더링할 컴포넌트를 연결합니다. 이를 통해 SPA(싱글 페이지 애플리케이션) 내에서도 각기 다른 URL을 사용할 수 있으며, 브라우저의 주소 표시줄을 통해 페이지를 전환할 수 있습니다.
2. React Router 설치하기
리액트 애플리케이션에 React Router를 추가하려면 다음 명령어로 패키지를 설치할 수 있습니다:
npm install react-router-dom
설치가 완료되면, 기본적인 라우팅을 설정할 준비가 끝났습니다.
3. 기본적인 라우팅 설정
React Router를 사용하기 위해 가장 먼저 해야 할 일은 BrowserRouter
와 Route
컴포넌트를 사용하는 것입니다. 기본적인 예제는 다음과 같습니다:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = () => <h2>Home Page</h2>;
const About = () => <h2>About Page</h2>;
const App = () => {
return (
<Router>
<div>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</div>
</Router>
);
};
export default App;
위의 코드에서 Router
컴포넌트는 애플리케이션의 루트 컴포넌트로, 그 내부에 여러 개의 Route
컴포넌트를 포함하고 있습니다. Switch
컴포넌트는 자식으로 받은 Route
중 첫 번째로 일치하는 것을 렌더링합니다. exact
속성을 추가하면 ‘/’ 경로가 정확히 맞아떨어질 때만 Home
컴포넌트를 렌더링합니다.
4. 동적 라우팅
이제 동적 라우팅을 구현해 보겠습니다. 동적 라우팅이란, URL의 일부가 동적으로 변할 수 있는 라우팅을 생성하는 방법입니다. 예를 들어, 블로그 포스트의 디테일 페이지를 구현할 때 특정 포스트의 ID를 URL의 일부로 사용하여 동적으로 해당 포스트를 로드할 수 있습니다.
const Post = ({ match }) => {
return <h2>Post ID: {match.params.id}</h2>;
};
const App = () => {
return (
<Router>
<div>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/post/:id" component={Post} />
</Switch>
</div>
</Router>
);
};
위의 예제에서 Post
컴포넌트는 URL의 파라미터를 사용하여 포스트 ID를 가져옵니다. match.params.id
를 통해 URL에서 동적으로 변하는 ID 값을 얻을 수 있습니다.
5. URL 파라미터 처리 방법
React Router를 사용하면서 중요한 것은 URL 파라미터를 처리하는 것입니다. URL 파라미터는 URL 경로의 일부로서, 특정 데이터를 동적으로 처리하기 위해 사용됩니다. 위에서 설명한 Post
컴포넌트는 URL 파라미터를 처리하는 좋은 예입니다.
여기서 URL 파라미터를 사용하여 해당 포스트의 내용을 가져오는 방법을 설명합니다. 예를 들어, 사용자가 포스트 개별 URL을 클릭했을 때, 서버에서 해당 포스트의 데이터를 가져오는 방법은 다음과 같습니다:
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Post = ({ match }) => {
const [post, setPost] = useState(null);
const postId = match.params.id;
useEffect(() => {
const fetchPost = async () => {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`);
const data = await response.json();
setPost(data);
};
fetchPost();
}, [postId]);
if (!post) return <p>Loading...</p>;
return (
<div>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
);
};
const App = () => {
return (
<Router>
<div>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/post/:id" component={Post} />
</Switch>
</div>
</Router>
);
};
위의 예제에서는 useEffect
hook을 사용하여 컴포넌트가 마운트될 때 API 요청을 보내고, 특정 포스트의 데이터를 가져옵니다. 가져온 후에는 상태를 업데이트하여 화면에 포스트 제목과 내용을 보여줍니다.
6. URL 쿼리 파라미터 처리하기
동적 라우팅 외에도 쿼리 파라미터를 통해 URL에 추가적인 데이터를 전달할 수 있습니다. 쿼리 파라미터는 URL의 ‘?’ 이후에 위치하며, 여러 개의 파라미터를 ‘&’로 구분합니다. 이를 React Router에서 처리하는 방법은 다음과 같습니다:
예를 들어, 사용자가 검색 결과를 확인할 수 있는 페이지를 만들고 싶다면, URL은 다음과 같은 형태가 될 수 있습니다:
http://example.com/search?query=react&page=2
이러한 쿼리 파라미터를 React Router의 useLocation
hook을 사용하여 가져올 수 있습니다:
import React from 'react';
import { BrowserRouter as Router, Route, Switch, useLocation } from 'react-router-dom';
const useQuery = () => {
return new URLSearchParams(useLocation().search);
};
const Search = () => {
let query = useQuery();
let searchTerm = query.get('query');
let page = query.get('page');
return (
<div>
<h2>Search Results for: {searchTerm}</h2>
<p>Page: {page}</p>
</div>
);
};
const App = () => {
return (
<Router>
<div>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/search" component={Search} />
</Switch>
</div>
</Router>
);
};
이 예제에서 useQuery
라는 커스텀 훅을 만들어 URL 쿼리 파라미터를 쉽게 가져올 수 있게 했습니다. searchTerm
과 page
변수에 쿼리 파라미터의 값을 할당하여 화면에 표시합니다.
7. Redirect와 Navigate 사용하기
사용자가 특정 조건을 만족하지 않을 때 다른 페이지로 리디렉션할 필요가 있을 수 있습니다. React Router에서는 Redirect
컴포넌트를 사용하여 이 작업을 수행할 수 있습니다. 아래는 사용자가 로그인된 상태가 아닐 때 로그인 페이지로 리다이렉트하는 예시입니다:
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
const ProtectedRoute = ({ component: Component, isAuthenticated, ...rest }) => {
return (
<Route
{...rest}
render={props =>
isAuthenticated ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> )
}
/>
);
};
const App = () => {
const isAuthenticated = false; // 예시를 위한 값입니다.
return (
<Router>
<div>
<Switch>
<Route path="/" exact component={Home} />
<ProtectedRoute path="/protected" component={Protected} isAuthenticated={isAuthenticated} />
<Route path="/login" component={Login} />
</Switch>
</div>
</Router>
);
};
위의 예제에서 ProtectedRoute
컴포넌트는 인증 여부에 따라 사용자를 원하는 페이지에 리다이렉트합니다. 사용자가 인증되지 않았다면 /login
페이지로 이동하게 됩니다.
8. BrowserRouter와 HashRouter
React Router는 다양한 라우터를 제공합니다. 여기서는 BrowserRouter
와 HashRouter
에 대해 설명합니다. BrowserRouter
는 HTML5의 history API를 사용하여 URL을 관리하며, 가장 일반적으로 사용됩니다. 반면에 HashRouter
는 해시(#)를 사용하여 URL 구조를 관리합니다. 두 라우터의 차이는 주로 서버 설정에 관련되어 있습니다.
일반적으로 서버에서 모든 경로를 처리해야 할 경우 BrowserRouter
를 사용합니다. 그러나 서버 설정이 복잡한 경우, HashRouter
를 사용하는 것이 편리할 수 있습니다.
import React from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
const App = () => {
return (
<HashRouter>
<div>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</div>
</HashRouter>
);
};
해시 라우터를 사용하면 URL이 다음과 같이 표시됩니다:
http://example.com/#/about
9. 결론
React Router를 활용하면 리액트 애플리케이션에서 페이지 간 네비게이션을 쉽게 관리할 수 있습니다. 동적 라우팅과 URL 파라미터 처리 등 다양한 기능을 통해 더욱 강력하고 유연한 애플리케이션을 구축할 수 있습니다. 지금까지 소개한 내용을 통해 React 애플리케이션에서 라우팅을 설정하고, 동적 데이터 처리 및 URL 파라미터를 사용하는 방법에 대해 이해했기를 바랍니다.
앞으로도 다양한 기능을 추가하고, 더 나은 사용자 경험을 제공하는 방향으로 애플리케이션을 발전시켜 나가시길 바랍니다. happy coding!