안녕하세요
오늘은 React 환경에서 react-scroll 라이브러리를 활용해
클릭 시 부드럽게 섹션으로 이동하는 스크롤 내비게이션을 만들어보겠습니다.
1. 먼저 생성돼 있는 react 프로젝트로 이동합니다.
cd [my-react-project]
Tailwind CSS 가 사용될 예정이니 아래 링크를 참고해 Tailwind css 를 설치해주세요
Installing with Vite - Installation
Integrate Tailwind CSS with frameworks like Laravel, SvelteKit, React Router, and SolidJS.
tailwindcss.com
2. react-scroll 설치
npm install react-scroll
- 이 라이브러리를 통해 스크롤 이벤트를 제어하고, 섹션 감지 및 부드러운 이동 효과를 줄 수 있습니다.
3. Tailwind CSS 설정
/* src/index.css */
@import "tailwindcss";
- Tailwind CSS v4 이상이라면 따로 @tailwind base;, @tailwind utilities; 같은 구문 없이도
index.css에 아래와 같이 작성만 되어 있으면 자동 적용됩니다
4. Header.jsx
import { Link } from 'react-scroll';
function Header() {
return (
<header className="fixed top-0 w-full bg-white shadow-md z-50">
<div className="max-w-5xl mx-auto px-6 py-4 flex justify-between items-center">
<h1 className="text-xl font-bold text-indigo-600">OOO.dev</h1>
<nav className="space-x-6 text-gray-700 font-medium">
<Link
to="home"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="cursor-pointer hover:text-indigo-500 transition-colors"
>
Home
</Link>
<Link
to="about"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="cursor-pointer hover:text-indigo-500 transition-colors"
>
About
</Link>
<Link
to="projects"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="cursor-pointer hover:text-indigo-500 transition-colors"
>
Projects
</Link>
<Link
to="contact"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="cursor-pointer hover:text-indigo-500 transition-colors"
>
Contact
</Link>
</nav>
</div>
</header>
);
}
export default Header;
react-scroll 의 주요 구성요소는 아래와 같습니다.
- to : 이동할 대상 id (ex: "projects")
- smooth : 부드러운 스크롤 효과 (true/false)
- offset : 위치 보정 값 (예: 고정된 헤더 높이만큼 -80)
- spy : 현재 보이는 섹션 감지하여 className에 적용
- duration : 스크롤 지속 시간 (ms 단위)
**참고: 프로젝트 구조는 아래와 같습니다.

5. Hero.jsx
import { Link } from 'react-scroll';
function Hero() {
return (
<section id="home" className="min-h-screen flex flex-col justify-center items-center text-center bg-gray-50 pt-20 px-6">
<h2 className="text-5xl font-bold text-gray-900 mb-4">Hi, I'm OOO 👋</h2>
<p className="text-lg text-gray-600 mb-6">
I build full-stack web & AI-powered apps that feel natural to use.
</p>
<Link
to="projects"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="bg-indigo-600 text-white px-6 py-3 rounded-lg text-lg hover:bg-indigo-500 transition cursor-pointer"
>
View My Work
</Link>
</section>
);
}
export default Hero;
6. Contact.jsx
import { Link } from 'react-scroll';
function Contact() {
return (
<section id="contact" className="min-h-screen bg-white py-20 px-6">
<div className="max-w-4xl mx-auto">
<div className="text-center mb-16">
<h2 className="text-4xl font-bold text-gray-900 mb-4">Get In Touch</h2>
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
I'm always interested in hearing about new opportunities and exciting projects.
Let's work together to bring your ideas to life!
</p>
</div>
<div className="grid md:grid-cols-2 gap-12">
<div>
<h3 className="text-2xl font-semibold text-gray-900 mb-6">Let's Connect</h3>
<div className="space-y-6">
<div className="flex items-center space-x-4">
<div className="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center">
<span className="text-xl">📧</span>
</div>
<div>
<h4 className="font-semibold text-gray-900">Email</h4>
<p className="text-gray-600">OOO@example.com</p>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center">
<span className="text-xl">📱</span>
</div>
<div>
<h4 className="font-semibold text-gray-900">Phone</h4>
<p className="text-gray-600">123-4567</p>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center">
<span className="text-xl">📍</span>
</div>
<div>
<h4 className="font-semibold text-gray-900">Location</h4>
<p className="text-gray-600">Seoul, Korea</p>
</div>
</div>
</div>
<div className="mt-8">
<h4 className="font-semibold text-gray-900 mb-4">Follow Me</h4>
<div className="flex space-x-4">
<a href="#" className="w-10 h-10 bg-indigo-600 rounded-full flex items-center justify-center text-white hover:bg-indigo-500 transition">
<span>📘</span>
</a>
<a href="#" className="w-10 h-10 bg-indigo-600 rounded-full flex items-center justify-center text-white hover:bg-indigo-500 transition">
<span>🐙</span>
</a>
<a href="#" className="w-10 h-10 bg-indigo-600 rounded-full flex items-center justify-center text-white hover:bg-indigo-500 transition">
<span>💼</span>
</a>
</div>
</div>
</div>
<div>
<h3 className="text-2xl font-semibold text-gray-900 mb-6">Send a Message</h3>
<form className="space-y-6">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-2">
Name
</label>
<input
type="text"
id="name"
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
placeholder="Your name"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
Email
</label>
<input
type="email"
id="email"
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
placeholder="your@email.com"
/>
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-2">
Message
</label>
<textarea
id="message"
rows={4}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
placeholder="Tell me about your project..."
></textarea>
</div>
<button
type="submit"
className="w-full bg-indigo-600 text-white py-3 px-6 rounded-lg text-lg hover:bg-indigo-500 transition"
>
Send Message
</button>
</form>
</div>
</div>
<div className="text-center mt-16">
<Link
to="home"
spy={true}
smooth={true}
offset={-80}
duration={500}
className="inline-flex items-center space-x-2 text-indigo-600 hover:text-indigo-500 transition cursor-pointer"
>
<span>↑</span>
<span>Back to Top</span>
</Link>
</div>
</div>
</section>
);
}
export default Contact;
7.App.jsx
마지막으로 진입 코드입니다.
import Header from "./components/Header";
import Hero from "./components/Hero";
import About from "./components/About";
import Projects from "./components/Projects";
import Contact from "./components/Contact";
function App() {
return (
<>
<Header />
<Hero />
<About />
<Projects />
<Contact />
</>
);
}
export default App;
결과물입니다.
위처럼 부드럽게 화면이 넘어가는 효과를 간단하게 구현해보았습니다.
현재는 단순히 화면만 넘어가는 구조이지만, 상세 페이지를 연결해 포트폴리오 사이트에 활용할 수도 있습니다.
'React' 카테고리의 다른 글
| [React] Motion 라이브러리 사용하여 스크롤 진행바 (scrollYProgress 사용) 애니메이션 구현하기 (6) | 2025.07.17 |
|---|---|
| [React] Three Fiber 로 3D 효과 만들기 (0) | 2025.07.16 |
| [React] 텍스트 입력 시 자동으로 필드 추가하기 (Material UI 활용) (2) | 2025.07.12 |
| [React] Hook 함수형 컴포넌트 (2) | 2025.06.30 |
| [React] 마크다운 프리뷰어 만들기 (0) | 2025.06.23 |