안녕하세요 오늘은 react-router-dom 을 사용하여 페이지 전환을 해보도록 하겠습니다.
슬라이드 카드 만들기에 이어서 진행할 예정입니다.
해당 게시글은 아래 링크에서 확인하실 수 있습니다.
[React] 슬라이드 카드 UI 만들기
안녕하세요. 오늘은 리액트를 사용해 슬라이드 카드 UI를 만들어보겠습니다. 슬라이드 카드는 이미지, 텍스트 등을 한 화면에서 넘기며 보여줄 수 있는 방식으로, 포트폴리오, 프로젝트 소개, 리
stickode.tistory.com
1. react-router-dom 설치
먼저 리액트 라우터 돔을 설치합니다.
Windows 개발 환경 기준 VS Code 의 터미널 단축키는 < Ctrl + ` > 입니다
npm install react-router-dom
2. 페이지 만들기 (프로젝트 구조)
src 안에 /page 디렉토리를 생성합니다.
총 4개의 페이지 (home, experiences, about, projects) 로 구성하고자 합니다.
4개의 자바 스크립트 파일을 만들어줍니다.
3. 상단 메뉴바 만들기
기존 슬라이드 카드를 home 화면으로 삼도록 하겠습니다.
App.js 파일에서 헤더를 추가해 상단 메뉴바 코드를 추가해줍니다
<header style={headerStyle}>
<div style={{ fontWeight: "bold", fontSize: "20px" }}>
<Link to="/" style={{ color: "white", textDecoration: "none" }}>
Hiii It's mee !
</Link>
</div>
<nav style={navStyle}>
<Link to="/" style={{ color: "white", textDecoration: "none" }}>
Home
</Link>
<Link to="/about" style={{ color: "white", textDecoration: "none" }}>
About
</Link>
<Link
to="/experience"
style={{ color: "white", textDecoration: "none" }}
>
Experience
</Link>
<Link
to="/projects"
style={{ color: "white", textDecoration: "none" }}
>
Projects
</Link>
</nav>
</header>
4. 라우터
라우터(Router)란 "어떤 주소(URL)"에 따라 어떤 페이지나 화면을 보여줄지 결정해주는 시스템입니다.
데이터가 목적지까지 도달하도록 경로를 설정하고 전송하는 역할을 합니다.
주소(URL) | 보여줄 화면(페이지) |
/ | 홈 화면 |
/about | About 소개 페이지 |
/projects | 로그인 화면 |
라우터는 위 주소를 각각 분기처리하여 어떤 페이지를 렌더링할지 결정합니다.
React 는 원래 "하나의 페이지에서 작동하는" Single Page Application (SPA)입니다.
그러나 웹사이트는 주로 한 개 이상의 페이지가 필요한 경우가 훨씬 많습니다.
이걸 가능하게 해주는 게 바로 <Router> 입니다.
return 값 전체를 <Router> 로 감싸서 "라우팅 기반"으로 동작할 것임을 선언합니다.
전체 코드입니다
App.js
import "./App.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import Slider from "react-slick";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import About from "./pages/about.js";
import Experience from "./pages/experiences.js";
import Projects from "./pages/projects.js";
// 슬라이드 카드 데이터
const cardData = [
{
title: "1. Wall Sina",
description:
"The innermost wall, where the royal family and nobles reside.",
image: "https://source.unsplash.com/random/800x400?city",
},
{
title: "2. Wall Rose",
description: "The middle wall, home to many of the general populace.",
image: "https://source.unsplash.com/random/800x400?nature",
},
{
title: "3. Wall Maria",
description:
"The outermost and largest wall, the first to fall during the Titans' initial attack.",
image: "https://source.unsplash.com/random/800x400?space",
},
];
// 커스텀 화살표
function PrevArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
left: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
←
</button>
);
}
function NextArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
right: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
→
</button>
);
}
// App 컴포넌트
function App() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
};
const headerStyle = {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "20px 40px",
backgroundColor: "#0d1b2a",
color: "white",
};
const navStyle = {
display: "flex",
gap: "20px",
alignItems: "center",
};
return (
<Router>
<header style={headerStyle}>
<div style={{ fontWeight: "bold", fontSize: "20px" }}>
<Link to="/" style={{ color: "white", textDecoration: "none" }}>
Hiii It's mee !
</Link>
</div>
<nav style={navStyle}>
<Link to="/" style={{ color: "white", textDecoration: "none" }}>
Home
</Link>
<Link to="/about" style={{ color: "white", textDecoration: "none" }}>
About
</Link>
<Link
to="/experience"
style={{ color: "white", textDecoration: "none" }}
>
Experience
</Link>
<Link
to="/projects"
style={{ color: "white", textDecoration: "none" }}
>
Projects
</Link>
</nav>
</header>
<Routes>
<Route
path="/"
element={
<div style={{ padding: "50px", textAlign: "center" }}>
<div className="slider-wrapper">
<Slider {...settings}>
{cardData.map((card, index) => (
<div key={index} className="slide">
<div
className="slide-background"
style={{
backgroundImage: `url(${card.image})`,
height: "400px",
backgroundSize: "cover",
backgroundPosition: "center",
position: "relative",
borderRadius: "20px",
overflow: "hidden",
}}
>
<div
className="text-box"
style={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
backgroundColor: "rgba(0,0,0,0.6)",
padding: "30px",
width: "80%",
maxWidth: "600px",
minWidth: "250px",
borderRadius: "20px",
textAlign: "center",
color: "white",
}}
>
<h2>{card.title}</h2>
<p>{card.description}</p>
</div>
</div>
</div>
))}
</Slider>
</div>
</div>
}
/>
<Route path="/about" element={<About />} />
<Route path="/experience" element={<Experience />} />
<Route path="/projects" element={<Projects />} />
</Routes>
</Router>
);
}
export default App;
about.js
About 코드입니다. experience, projects 도 같은 방식으로 작성하였습니다.
function About() {
return (
<div style={{ padding: "50px", textAlign: "center" }}>
<h1>About Page</h1>
<p>이곳은 소개 페이지입니다.</p>
</div>
);
}
export default About;
시연 영상입니다
'React' 카테고리의 다른 글
[React] 좋아요 버튼 클릭 시 확인 모달 띄우기 (0) | 2025.06.04 |
---|---|
[React] useState 로 좋아요 버튼 상태 관리하기 (0) | 2025.05.28 |
[React] 슬라이드 카드 UI 만들기 (0) | 2025.05.15 |
[React] 인증번호 타이머 만들기 (0) | 2023.12.22 |
[React] 리액트 아이콘 사용하여 아이콘 적용하기 (0) | 2023.12.12 |