React기반 포트폴리오 사이트입니다. 매거진스타일을 적용하였고 이미지 슬라이드나 프로젝트는 추가될 예정임으로 하나의 컴포넌트내에 json형태의 데이터를 만들고 fetch함수와 map을 이용하여 작업하였습니다.
언어 : React js, javascript
Style : sass, styled-component
Library : react-icons, react-slider-swiper, page-flip
Verrsion control Tool : Git
App js : fetch함수를 이용하여 data호출하고 해당 페이지와 컴포넌트에 넘겨준다.
page폴더 : 페이지와 해당 컴포넌트, 데이터를 담은 컴포넌트를 넣었다.
function About() {
const [tab, setTab] = useState(0);
const stackContent = {
0: <TechStack />,
1: <Workexperience />,
2: <DesignSkill />,
3: <ProjectCard />,
4: <ToyProjectCard />,
};
return (
<AboutWrap>
<div className="aboutContainer">
<h3>About</h3>
<Category tab={tab} setTab={setTab} />
<div className="contentContainer">{stackContent[tab]}</div>
</div>
</AboutWrap>
);
}
export default About;
function Category({ tab, setTab }) {
return (
<ul>
<li
className={`${tab === 0 ? "active" : ""}`}
onClick={() => {
setTab(0);
}}
>
Tech <span className="hide">Stack</span>,
</li>
<li
className={`${tab === 1 ? "active" : ""}`}
onClick={() => {
setTab(1);
}}
>
Design<span className="hide">Skill</span> ,
</li>
<li
className={`${tab === 2 ? "active" : ""}`}
onClick={() => {
setTab(2);
}}
>
Work<span className="hide">experience</span>,
</li>
<li
className={`${tab === 3 ? "active" : ""}`}
onClick={() => {
setTab(3);
}}
>
Project,
</li>
<li
className={`${tab === 4 ? "active" : ""}`}
onClick={() => {
setTab(4);
}}
>
Toy<span className="hide"> Project</span>,
</li>
</ul>
);
}
export default Category;
시현영상
import "swiper/scss";
import "swiper/scss/pagination";
import "swiper/scss/navigation";
import { Swiper, SwiperSlide } from "swiper/react";
import { Pagination, Navigation, Autoplay } from "swiper";
function Slider() {
return (
<Swiper
spaceBetween={10}
autoplay={{
delay: 2500,
disableOnInteraction: false, //스와이프 후 자동재생
}} //자동 시간
loop={true} //무한슬라이드
height={800}
pagination={{ type: "fraction" }}
navigation={true}
modules={[Autoplay, Pagination, Navigation]} //modules에 기능 넣기
>
{ImgSliderData?.map((slideData) => {
return (
<SwiperSlide key={slideData.id}>
<img src={slideData.src} alt="pic" className="sliderImg" />
</SwiperSlide>
);
})}
</Swiper>
);
}
export default Slider;
시현 영상
App js에서 데이터를 fetch로 호출하여 Main컴포넌트로 넘겨주고, 데이터가 구현되는 자리인 About js내에 Project js인 카드에 map()으로 호출하고 반환한다.
어떻게 하나의 데이터를 맞춰서 넣어줄까 고민하다가 고유값이 id를 키값으로 지정후 키값을 조건문으로 사용하였다.
function ToyProjectCard({ projectData }) {
const [introduce, setIntroduce] = useState(0); // 데이터를 맞출 키값 id
const [toyPrjModal, setToyPrjModal] = useState(false);
return (
<>
{projectData.map((prjCard) => {
return (
<div key={prjCard.id}>
<img
onClick={() => {
setIntroduce(prjCard.id);
setToyPrjModal(true);
}}
src={prjCard.imgSrc} alt="toyprojectImg" />
<button
onClick={() => {
setIntroduce(prjCard.id);
setToyPrjModal(true);
}}
> 더보기 </button>
</div>
);
})}
{toyPrjModal === true ? (
<ToyPrjDetail
project={projectData} // 데이터
setToyPrjModal={setToyPrjModal} // modal 닫기 버튼
introduce={introduce} // 조건문에 사용할 키값 id
/>
) : null}
</StyledToyCard>
);
}
export default ToyProjectCard;
function ToyProjectDetail({ project, setToyPrjModal, introduce }) {
return (
<div>
{project.map((projectList) => {
if (projectList.id !== introduce) return null;
return (
<div key={projectList.id}>
// 데이터받아오기
</div>
);
})}
</div>
</StyledToyPrj>
);
}
export default ToyProjectDetail;
시현 영상
혼자 기획하고 작업한 사이트인만큼 기능하나하나에 고민을 하였다. swiper는 손쉽게 구현은 되지만 커스터마이징이 어려웠고, 클릭하면 연결된 데이터가 구현되는 기능인 카테고리와 카드형 데이터는 기능은 비슷해보이지만 추후 유지보수에 맞춰 다르게 코딩하였다. 간단하게 생각하면 간단하고 어렵게 생각하면 어려워지는게 개발인듯 하다. 기능을 생각하며 로직을 짜고 기능이 구현될때 뿌듯하다. 기세를 몰아 추후 아트웍을 모아놓은 페이지도 구현해야지!!