<< 학습 목표 >>
1. 리엑트 라우터(Router) 라이브러리가 필요한 이유를 설명할 수 있다.
2. 리엑트 라우터(Router) 라이브러리를 사용해 SPA를 구현할 수 있다.
3. URL 파라미터를 사용할 수 있다.
리엑트가 SPA ( Single Page Application ) 을 구현할 수 있다고 했는데 지금까지는 페이지 하나에서 모두 처리했음
이번에는 리엑트로 SPA를 구현할 수 있는 라우터(Router) 를 배워보자
라우터를 사용하려면 프로젝트에 react-router-dom 라이브러리를 설치해야함
vs code 에서 터미널을 열고 프로젝트로 이동한 후 프로젝트에 react-router-dom 라이브러리를 설치하자
1. 프로젝트로 이동 : cd study-project
2. react-router-dom 라이브러리 설치 : npm install react-router-dom
리엑트 라우터는 브라우저의 URL 경로를 사용하여 특정 컴포넌트를 불러오는(렌더링하는) 라이브러리임
라우터를 사용하는 이유는 다음과 같음
1. 브라우저의 URL 경로를 사용하여 컴포넌트를 보여줄 수 있음
2. SPA는 모든 컨텐츠(컴포넌트)를 하나의 페이지에서 보여줌
이러한 SPA를 구현하려면 브라우저의 URL 경로를 사용하여 컴포넌트를 보여줘야함
리엑트 라우터는 이러한 SPA를 구현하는 데 필요한 기능을 제공함
3. 리엑트 라우터를 사용하면 중첩된 컴포넌트 간의 라우팅을 처리할 수 있음
4. 리엑트 라우터는 브라우저의 히스토리를 관리할 수 있음
이를 통해 뒤로가기, 앞으로가기 버튼 등을 사용하여 페이지 이동을 처리할 수 있음
리엑트 라우터의 장점은 다음과 같음
1. SPA 구현이 용이함
2. 중첩된 라우팅을 지원함
3. 히스토리 관리가 가능함
4. 동적 라우팅을 지원함
리엑트 라우터의 단점은 다음과 같음
1. 학습을 하기 위해 시간이 다소 소요될 수 있음
2. 라우터를 남용하면 프로젝트가 필요 이상으로 복잡해질 수 있음
3. SEO 최적화가 어려움
SEO란 검색 엔진 최적화인데 검색 사이트에서 검색이 되고 상위에 노출될 수 있도록 하는 작업을 뜻함
이를 위해서 많은 사이트에서 각 컨텐츠(페이지, 컴포넌트)별로 페이지 내 다양한 키워드를 넣어둠
그러나 리엑트 라우터는 SPA 이므로 하나의 페이지에서 모든 컨텐츠를 다 보여줘 각 페이지별 다양한 키워드를 넣기 어렵다는 점 등 SEO 최적화가 어렵다는 단점이 있음
SPA를 구현하기 위해서는 라우터 라이브러리가 필수이지만 단점도 있으니 단점을 해결할 방안도 찾는것이 좋음
이제 리엑트 라우터를 실습하자
라우터를 실습하기 위해 프로젝트 -> src -> chapter04 폴더 내 아래와 같은 컴포넌트들을 추가할 것
1. Component02.jsx : 브라우저의 URL에 맞는 페이지를 불러올 컴포넌트
2. Home.jsx : 브라우저의 URL이 / 일 경우 보여줄 컴포넌트
3. About.jsx : 브라우저의 URL이 /about 일 경우 보여줄 컴포넌트
4. List.jsx : 브라우저의 URL이 /topics 일 경우 보여줄 컴포넌트
<< 1. Component02.jsx >>
import React from 'react';
function Component02() {
return(
<div style={{margin: "20px"}}>
<nav>
<span>Home</span>
<span>About</span>
<span>List</span>
</nav>
<div>
{/* URL에 맞는 컴포넌트를 보여줄 영역 */}
</div>
</div>
);
}
export default Component02;
위 컴포넌트에서 nav 태그가 사이트 메뉴 역할을 함
nav 태그 밑에 있는 div 태그가 메뉴에 맞는 컴포넌트를 보여줄 태그임
HTML만 사용했다면 nav 태그 내 span 태그에 a 태그를 넣어야하지만 리엑트 라우터의 경우 Link 컴포넌트를 사용함
<< 코드 설명 >>
(1). Link 컴포넌트를 사용하기 위해서는 import 를 해야함
(2). 링크가 필요한 곳에 a 태그 대신 Link 컴포넌트를 사용함
Link 태그의 to 속성이 a 태그의 href 속성과 같은 역할을 함
브라우저 URL에 맞는 컨텐츠를 보여줄 영역에는 Routes 컴포넌트와 Route 컴포넌트를 사용함
<< 코드 설명 >>
(1). Routes, Route 컴포넌트를 사용하기 위해서는 각 컴포넌트를 import 해야함
(2). Route 컴포넌트를 사용해 브라우저 URL에 맞는(path 속성) 컴포넌트를 불러오도록 설정함(element 속성)
그 후 Route 컴포넌트들을 Routes 컴포넌트로 감싸야함
Component02 컴포넌트의 마지막으로 Link 컴포넌트들과 Routes 컴포넌트를 BrowserRouter 컴포넌트로 감싸야함
< < 코드 설명 >>
(1). BrowserRouter 컴포넌트를 사용하기 위해서는 import를 해야함
(2). Link 컴포넌트부터 Routes 컴포넌트까지 BrowserRouter 컴포넌트로 감싸야 Link, Routes 컴포넌트가 동작함
이제 브라우저 URL에 따라 페이지에 보여줄 컴포넌트들을 추가하자
컴포넌트는 아래와 같이 간단하게 추가할 것임
프로젝트 -> src -> chapter04 -> Home.jsx
import React from 'react';
function Home() {
return(
<div>
<h1>Home 컴포넌트</h1>
</div>
);
}
export default Home;
프로젝트 -> src -> chapter04 -> About.jsx
import React from 'react';
function About() {
return(
<div>
<h1>About 컴포넌트</h1>
</div>
);
}
export default About;
프로젝트 -> src -> chapter04 -> List.jsx
import React from 'react';
function List() {
return(
<div>
<h1>List 컴포넌트</h1>
</div>
);
}
export default List;
Component02 컴포넌트에 화면에 보여줄 컴포넌트들을 불러오자(1)
Component02 컴포넌트를 웹 페이지에 출력해보자
각 메뉴를 클릭하면 URL이 이동하면서 URL에 맞는 각 컴포넌트들이 보임
지금 페이지들의 링크 구조를 보면 다음과 같음
페이지들의 링크 구조를 다음과 같이 추가하려면 어떻게 해야할까?
즉, 지금은 Component02 컴포넌트에서 링크를 눌러 Home, About, List 컴포넌트를 불러오고 있는 구조임
여기에 List 컴포넌트에 링크를 추가해 List 컴포넌트에서 링크를 눌러 part1, part2 컴포넌트로 이동하는 구조를 추가하고 싶음
그럴 때는 우선 List 컴포넌트에 이동할 수 있게 링크를 추가해야함
<< List 컴포넌트 소스 코드 >>
더보기
import React from 'react';
import { Link } from 'react-router-dom';
function List() {
return(
<div>
<h1>List 컴포넌트</h1>
<ul>
<li><Link to="/list/part1">Part1</Link></li>
<li><Link to="/list/part2">Part2</Link></li>
</ul>
</div>
);
}
export default List;
그 후 Component02 컴포넌트의 Routes 안에 Route 컴포넌트로 URL에 맞는 컴포넌트를 보여주도록 할 수 있음
<< Component02 컴포넌트 소스 코드 >>
더보기
import React from 'react';
import { Link, Routes, Route, BrowserRouter } from 'react-router-dom';
import Home from './Home';
import About from './About';
import List from './List';
import ListPart1 from './ListPart1';
import ListPart2 from './ListPart2';
function Component02() {
return(
<div style={{margin: "20px"}}>
<BrowserRouter>
<nav>
<span><Link to="/">Home</Link></span>
<span><Link to="/about">About</Link></span>
<span><Link to="/list">List</Link></span>
</nav>
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/list" element={<List />} />
<Route path="/list/part1" element={<ListPart1 />} />
<Route path="/list/part2" element={<ListPart2 />} />
</Routes>
</div>
</BrowserRouter>
</div>
);
}
export default Component02;
컴포넌트가 GET 파라미터 값을 전달 받았을 때 컴포넌트에서 전달 받은 GET 파라미터는 어떻게 꺼낼까?
다음과 같이 useLocation 훅을 사용해 꺼낼 수 있음
<< List 컴포넌트 >>
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
function List() {
const location = useLocation();
const parameters = new URLSearchParams(location.search);
const value = parameters.get("name");
return(
<div>
<h1>List 컴포넌트</h1>
{ value != null && <p>전달 받은 name 파라미터의 값은 {value} 입니다</p> }
<ul>
<li><Link to="/list/part1">Part1</Link></li>
<li><Link to="/list/part2">Part2</Link></li>
</ul>
</div>
);
}
export default List;
<< 코드 설명 >>
(1). useLocation 훅을 사용하기 위한 import
(2). useLocation 훅을 사용해 JS의 location 객체를 리엑트로 가져옴
(3). URLSearchParams 클래스를 사용해 location 객체가 가지고 있는 GET 파라미터 값들을 꺼내기 쉽게 변환함
변환한 후 parameters 변수에 저장
(4). get 함수를 사용해 parameters 변수에 저장된 파라미터 값을 꺼내 value 변수에 저장
이때 꺼낼 파라미터의 이름을 인자로 넣음
위 코드는 GET 파라미터로 name=값 으로 전달했기 때문에 name 파라미터 값을 꺼내는 코드임
(5). 꺼낸 GET 파라미터를 출력함
또한 URL의 경로 중 일부를 파라미터로 사용할 수도 있음
Component02 컴포넌트에 URL의 경로 중 일부를 파라미터로 사용할 수 있도록 설정해보자
<< Component02 컴포넌트 소스 코드 >>
import React from 'react';
import { Link, Routes, Route, BrowserRouter } from 'react-router-dom';
import Home from './Home';
import About from './About';
import List from './List';
import ListPart1 from './ListPart1';
import ListPart2 from './ListPart2';
import AboutWho from './AboutWho';
function Component02() {
return(
<div style={{margin: "20px"}}>
<BrowserRouter>
<nav>
<span><Link to="/">Home</Link></span>
<span><Link to="/about">About</Link></span>
<span><Link to="/about/me">About Me</Link></span>
<span><Link to="/about/you">About Your</Link></span>
<span><Link to="/list">List</Link></span>
</nav>
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/about/:who" element={<AboutWho />} />
<Route path="/list" element={<List />} />
<Route path="/list/part1" element={<ListPart1 />} />
<Route path="/list/part2" element={<ListPart2 />} />
</Routes>
</div>
</BrowserRouter>
</div>
);
}
export default Component02;
<< 코드 설명 >>
(1). about URL 다음에 /me 또는 /you 경로를 더 붙인 링크를 추가했음
(2). /about/me, /about/you 를 /list/part1, /list/part2 처럼 처리할 수도 있지만 /about/me, /about/you 는 me, you 를 파라미터로 사용하기 위해 path가 /about/:who 인 Route 컴포넌트를 추가
:who 가 아니어도 됨 :a, :b 와 같이 아무 문자나 가능하나 위와 같이 의미 있는 문자를 사용하는게 좋음
/about/me, /about/you 모두 (2)의 Route가 지정한 컴포넌트인 AboutWho 컴포넌트가 보임
프로젝트 -> src -> Chapter04 -> AboutWho.jsx 를 추가하고 아래 코드를 추가하자
import React from 'react';
import { useParams } from 'react-router-dom';
function AboutWho() {
const {who} = useParams();
return(
<div>
<h1>About</h1>
<h3>{who} 입니다</h3>
</div>
);
}
export default AboutWho;
<< 코드 설명 >>
(1). URL 중 일부를 파라미터로 사용하기 위해서는 useParams 훅을 import 해야함
(2). URL 중 일부를 파라미터로 가져오기 위해 useParams 훅을 사용했음
Component02 컴포넌트 소스 코드 에서 봤던 me 또는 you 가 who 변수에 저장됨
(3). who 변수에 저장한 파라미터를 출력