프로젝트에서 구현하려고 했던 부분
- 가장 첫 번째 이미지가 기본이미지로 오도록 하고, 사진을 클릭하면 해당 사진으로 넘어가도록 구현
- prev, next 버튼을 누르면 이미지를 이동
UI 만들기
import FestivalImage from "../assets/FestivalImage1.png"
import FestivalImage2 from "../assets/FestivalImage2.png"
import FestivalImage3 from "../assets/FestivalImage3.png"
const images = [ /* 이미지 경로를 리스트로 저장 */
{
source: FestivalImage,
},
{
source: FestivalImage2,
},
{
source: FestivalImage3,
},
];
const ImageContent = () => {
return (
<ImageContentWrap>
<FestivalMainImageWrap>
<FestivalMainImage src={FestivalImage} alt="Festival Image"></FestivalMainImage>
</FestivalMainImageWrap>
{images.map((image, index) => (
<PreviewImage
key={index}
src={image.source}
alt={`Image ${index}`}
/>
))}
</ImageContentWrap>
);
};
우선 이미지를 import해서, map을 이용해 이미지가 보이도록 구현했다.
const ImageContentWrap = styled.div `
display: flex;
justify-content: center;
flex-wrap: wrap;
`
const FestivalMainImage = styled.img `
margin-top: 50px;
border-radius: 30px;
`;
const FestivalMainImageWrap = styled.div`
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 10px;
`
const PreviewImage = styled.img `
width: 80px;
height: 80px;
object-fit: cover;
margin-right: 10px; /*사진 크기에 맞게 잘라짐*/
`
styled-component 부분은 이렇게 디자인 했다.
UI가 완성된 부분
기능 추가 _ 사진 누르면 해당 사진으로 바뀌는 기능
const ImageContent = () => {
const [selectedImage, setSelectedImage] = useState(images[0]);
const onclickImage = (image) => {
setSelectedImage(image);
};
return (
<ImageContentWrap>
<FestivalMainImageWrap>
<FestivalMainImage src={selectedImage.source} alt="Festival Image"></FestivalMainImage>
</FestivalMainImageWrap>
{images.map((image, index) => (
<PreviewImage
key={index}
src={image.source}
alt={`Image ${index}`}
onClick={() => onclickImage(image)}
/>
))}
</ImageContentWrap>
);
};
- selectedImage라는 상태 추가 -> 현재 선택된 이미지를 나타내는 상태 (기본값은 첫 번째 이미지)
- onClickImage라는 함수로 클릭되었을 때 함수가 실행되면서 상태가 변경되도록 추가
기능 추가 _ prev, next 버튼
const ImageContent = () => {
const [selectedImageIndex, setSelectedImageIndex] = useState(0);
const onClickImage = (index) => {
setSelectedImageIndex(index);
};
const onNextImage = () => { /* next버튼을 눌렀을 때 실행되는 함수 */
setSelectedImageIndex((prevIndex) => (prevIndex + 1) % images.length);
}; /* 이미지 Index가 하나 늘어나도록 구현 */
const onPrevImage = () => { /* prev버튼을 눌렀을 때 실행되는 함수 */
setSelectedImageIndex((prevIndex) =>
prevIndex === 0 ? images.length - 1 : prevIndex - 1
); /* 이미지 Index가 하나 줄어들도록 구현 */
};
return (
<ImageContentWrap>
<FestivalMainImageWrap>
<ButtonIcon xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40" fill="none" onClick={onPrevImage}>
<path d="M25 30L15 20L25 10" stroke="#949494" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</ButtonIcon> /* prevButton 부분, onClick={onPrevImage}을 추가함 */
<FestivalMainImage src={images[selectedImageIndex].source} alt="Festival Image"></FestivalMainImage>
<ButtonIcon xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40" fill="none" onClick={onNextImage}>
<path d="M15 30L25 20L15 10" stroke="#949494" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</ButtonIcon> /* nextButton 부분, onClick={onNextImage}을 추가함 */
</FestivalMainImageWrap>
{images.map((image, index) => (
<PreviewImage
key={index}
src={image.source}
alt={`Image ${index}`}
onClick={() => onClickImage(image)}
/>
))}
</ImageContentWrap>
);
};
const ImageContentWrap = styled.div `
display: flex;
justify-content: center;
flex-wrap: wrap;
`
const FestivalMainImage = styled.img `
width: 800px;
margin-top: 50px;
border-radius: 30px;
`;
const FestivalMainImageWrap = styled.div`
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 10px;
`
const PreviewImage = styled.img `
width: 80px;
height: 80px;
object-fit: cover;
margin-right: 10px; /*사진 크기에 맞게 잘라짐*/
cursor: pointer;
`
const ButtonIcon = styled.svg `
cursor: pointer;
margin-top: 21%;
margin-left: 30px;
margin-right: 30px;
`
완성된 모습
'개발공부 > REACT' 카테고리의 다른 글
[React] API의 정의, 장/단점, API 사용하기 _ JSON, fetch 함수 (1) | 2023.11.25 |
---|---|
[React] 사진 더보기 접기 기능, 그라데이션 적용 (0) | 2023.08.11 |
[React] react-calendar 라이브러리로 캘린더 만들기 (3) | 2023.08.02 |
List, Key를 이용해 출석부 출력하기 실습 [처음 만난 리액트 #29] (0) | 2023.02.19 |
Lists and Keys (리스트, 키) / 여러 개의 컴포넌트에 렌더링하기 [처음 만난 리액트 #28] (0) | 2023.02.18 |