참고) ctrl + u 하면 소스 나옴
기존에 사용하던 HTML,CSS,JS 파일을
REACT로 변환해 보도록 하겠다.
vite로 새로운 폴더를 만들어준다.
html파일의 images 폴더를
정적 파일의 경우 (변하지 않는) public 폴더에 넣어준다.
html파일의 폰트오썸와 타이틀도 복사해서 넣어준다.
그리고 images 폴더 내에 있는 페비콘을 링크해서 페비콘도 변경한다.
변경됨을 확인 가능하다.
이제 CSS를 넣어본다.
Index.css
기존의 css를 삭제하고
style.css를 복사해서 붙여넣음
App.jsx도 필요없는 부분은 다 삭제하고 정리한다.
그리고 html파일에서 nav 부터 footer까지 복사해서 App.jsx에 붙여넣기한다.
그리고 class => className으로 변경한다.
ctrl +h하면 특정 단어를 찾아서 바꾸기 가능하다
에러 사라짐
이미지 파일들도 /images로 바꾼다.
그 다음 이제 컴포넌트로 나눌것이다.
각 컴포넌트 파일을 만든다.
그리고 App.jsx파일을 분리해서 넣는다
잘 분리해서 넣었는지 체크한다.
각각의 컴포넌트를 데이터를 가지고 만들거임
data.js를 만든다.
import tour1 from "/images/tour-1.jpeg";
import tour2 from "/images/tour-2.jpeg";
import tour3 from "/images/tour-3.jpeg";
import tour4 from "/images/tour-4.jpeg";
export const pageLinks = [
{ id: 1, href: "#home", text: "home" },
{ id: 2, href: "#about", text: "about" },
{ id: 3, href: "#services", text: "services" },
{ id: 4, href: "#tours", text: "tours" },
];
export const socialLinks = [
{ id: 1, href: "https://www.twitter.com", icon: "fab fa-facebook" },
{ id: 2, href: "https://www.twitter.com", icon: "fab fa-twitter" },
{ id: 3, href: "https://www.twitter.com", icon: "fab fa-squarespace" },
];
이제 PageLinks의 데이터를 가져와서 Navbar를 반복문으로 만들어줄거임
{/* <!-- left this comment on purpose --> */}
<ul className="nav-links" id="nav-links">
{pageLinks.map((link) => {
return (
<li key={link.id}>
<a href={link.href} className="nav-link">
{link.text}
</a>
</li>
);
})}
</ul>
PageLinks를 import 해주고, map을 사용해서 li태그를 반복한다.
link.id, text의 값들은 data.js에 있다.
마찬가지로
icon (socailLinks)도 반복문으로 변경한다.
<ul className="nav-icons">
{socialLinks.map((link) => {
return (
<li key={link.id}>
<a href={link.href} target="_blank" className="nav-icon">
<i className={link.icon}></i>
</a>
</li>
);
})}
</ul>
정상적으로 출력하는지 확인한다.
그리고 각 section의 Title도 반복되는것을 확인 가능하다
그래서 컴포넌트로 만들어줄거임
Title.jsx 컴포넌트 생성
const Title = ({ title, subTitle }) => {
return (
<div className="section-title">
<h2>
{title} <span>{subTitle}</span>
</h2>
</div>
);
};
export default Title;
각 섹션의 title을 Title컴포넌트로 교체한다.
Serices를 보면 같은 카드가 반복되는것을 확인 가능하다.
이 부분도 data로 처리해서 불러오도록 하겠다.
export const services = [
{
id: 1,
icon: "fas fa-wallet fa-fw",
title: "saving money",
text: "Lorem ipsum dolor sit amet consectetur adipisicing elit Asperiores, officia.",
},
{
id: 2,
icon: "fas fa-tree fa-fw",
title: "endless hiking",
text: "Lorem ipsum dolor sit amet consectetur adipisicing elit Asperiores, officia.",
},
{
id: 3,
icon: "fas fa-socks fa-fw",
title: "amazing comfort",
text: "Lorem ipsum dolor sit amet consectetur adipisicing elit Asperiores, officia.",
},
];
Serviecs.jsx
import { services } from "../data";
import Title from "./Title";
const Services = () => {
return (
<section className="section services" id="services">
<Title title="OUR" subTitle="SERVICES" />
<div className="section-center services-center">
{services.map((service) => {
return (
<article className="service" key={service.id}>
<span className="service-icon">
<i className={service.icon}></i>
</span>
<div className="service-info">
<h4 className="service-title">{service.title}</h4>
<p className="service-text">{service.text}</p>
</div>
</article>
);
})}
</div>
</section>
);
};
export default Services;
Tours 섹션도 마찬가지다.
//투어 섹션
export const tours = [
{
id: 1,
image: tour1,
date: "august 26th, 2020",
title: "Tibet Adventure",
info: ` Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque vitae tempore voluptatum maxime reprehenderit eum quod exercitationem fugit, qui corporis.`,
location: "china",
duration: 6,
cost: 2100,
},
{
id: 2,
image: tour2,
date: "october 1th, 2020",
title: "best of java",
info: ` Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque vitae tempore voluptatum maxime reprehenderit eum quod exercitationem fugit, qui corporis.`,
location: "indonesia",
duration: 11,
cost: 1400,
},
{
id: 3,
image: tour3,
date: "september 15th, 2020",
title: "explore hong kong",
info: ` Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque vitae tempore voluptatum maxime reprehenderit eum quod exercitationem fugit, qui corporis.`,
location: "hong kong",
duration: 8,
cost: 5000,
},
{
id: 4,
image: tour4,
date: "december 5th, 2019",
title: "kenya highlights",
info: ` Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque vitae tempore voluptatum maxime reprehenderit eum quod exercitationem fugit, qui corporis.`,
location: "kenya",
duration: 20,
cost: 3300,
},
];
Tours.jsx
import { tours } from "../data";
import Title from "./Title";
const Tours = () => {
return (
<section className="section" id="tours">
<Title title="FEATURED" subTitle="TOURS" />
<div className="section-center featured-center">
{tours.map((tour) => {
return (
<article className="tour-card" key={tour.id}>
<div className="tour-img-container">
<img src={tour.image} className="tour-img" alt="" />
<p className="tour-date">{tour.date}</p>
</div>
<div className="tour-info">
<div className="tour-title">
<h4>{tour.title}</h4>
</div>
<p>{tour.info}</p>
<div className="tour-footer">
<p>
<span>
<i className="fas fa-map"></i>
</span>
{tour.location}
</p>
<p>{tour.duration}</p>
<p>{tour.cost}</p>
</div>
</div>
</article>
);
})}
</div>
</section>
);
};
export default Tours;
Footer 도 Navbar에서 link와 icon을 불러온것과 동일하게 data를 사용해서 map으로 반복문 처리한다.
import { pageLinks, socialLinks } from "../data";
const Footer = () => {
return (
<footer className="section footer">
<ul className="footer-links">
{pageLinks.map((link) => {
return (
<li key={link.id}>
<a href={link.href} className="footer-link">
{link.text}
</a>
</li>
);
})}
</ul>
<ul className="footer-icons">
{socialLinks.map((link) => {
return (
<li key={link.id}>
<a href={link.href} target="_blank" className="footer-icon">
<i className={link.icon}></i>
</a>
</li>
);
})}
</ul>
<p className="copyright">
copyright © Backroads travel tours company
<span id="date">{new Date().getFullYear()}</span> all rights reserved
</p>
</footer>
);
};
export default Footer;
매년 바뀌는 년도를 반영하기 위해서 자바스크립트 사용한다.
현재 모바일 버전에서는 토글버튼이 작동하지 않는다.
Navbar.jsx
const Navbar = () => {
const [showLink, setShowLink] = useState(false);
const toggleLink = () => {
showLink ? setShowLink(false) : setShowLink(true);
};
useState로 showLink 상태를 표시한다.
그리고 토글 버튼을 눌렀을 때 onclick 이벤트로 toggleLink함수를 실행한다.
toggleLInk 함수는 showLink가 참이면 false로 false면 true 변경한다.
<nav className="navbar">
<div className="nav-center">
<div className="nav-header">
<img src="/images/logo.svg" className="nav-logo" alt="backroads" />
<button
type="button"
onClick={toggleLink}
className="nav-toggle"
id="nav-toggle"
>
<i className="fas fa-bars"></i>
</button>
</div>
{/* <!-- left this comment on purpose --> */}
<ul
className={`${showLink ? "nav-links show-links" : "nav-links"}`}
id="nav-links"
>
{pageLinks.map((link) => {
return (
<li key={link.id}>
<a href={link.href} className="nav-link">
{link.text}
</a>
</li>
);
})}
</ul>
토글 버튼이 잘 작동하는지 테스트한다.
하지만 한번 토글버튼을 클릭하면 나타나지 않는다.
그래서
useEffect를 통해서 4초뒤에 다시 토글버튼이 나타나도록 코드를 추가한다.
//4초 뒤에 showLink를 false로 바꿔줌
useEffect(() => {
if (showLink) {
setTimeout(() => {
setShowLink(false);
}, 4000);
}
}, [showLink]);
'FRONTEND > React' 카테고리의 다른 글
프로젝트 관리 (0) | 2023.11.29 |
---|---|
[HTML 변환] HTML -> REACT 변환 2 (1) | 2023.11.28 |
[쿠킹레시피] 배포하기 (0) | 2023.11.27 |
[쿠킹레시피] 파이어 베이스 연결하기 (레시피 삭제하기) (2) | 2023.11.27 |
[쿠킹레시피] 파이어 베이스 연결하기 (레시피 상세화면, 레시피 추가 DB연결) (1) | 2023.11.27 |