본인이 직접 작성한 코드가 아닌, 다른 사람의 코드를 보고 해석하려는 의도로 블로그를 작성합니다..!
출처 : https://github.com/wecode-bootcamp-korea/24-2nd-FX-frontend/blob/feature/Carousel/src/Components/Carousel.js
<Container>
<HeaderBox
onMouseEnter={showHiddenHeader}
onMouseLeave={hideHiddenHeader}>
<Header>지금 뜨는 콘텐츠 </Header>
<HiddenHeader hiddenStatus={hiddenStatus}>
모두 보기 >
</HiddenHeader>
<button onClick={handleModal}>모달열기</button>
</HeaderBox>
<Slider>
<LeftArrow onClick={handleLeftArrow}><</LeftArrow>
<CardWrapper curXAxis={curXAxis}>
{cardsData.map(card => {
return (
<Card
id={card.id}
img={card.thumb_nail}
onClick={handleModal}/>
);
})}
</CardWrapper>
<RightArrow onClick={handleRightArrow}>></RightArrow>
</Slider>
<ModalPortal>
<Modal onClose={handleModal} modalOn={modalOn} />
</ModalPortal>
</Container>
<HeaderBox
onMouseEnter={showHiddenHeader}
onMouseLeave={hideHiddenHeader}>
<Header>지금 뜨는 콘텐츠 </Header>
<HiddenHeader hiddenStatus={hiddenStatus}>
모두 보기 >
</HiddenHeader>
<button onClick={handleModal}>모달열기</button>
</HeaderBox>
const showHiddenHeader = () => {
setHiddenStatus(true);
};
const hideHiddenHeader = () => {
setHiddenStatus(false);
};
const handleModal = () => {
setModalOn(!modalOn);
};
const [hiddenStatus, setHiddenStatus] = useState(false);
const HeaderBox = styled.div`
margin-bottom: 15px;
margin-left: 50px;
color: #e5e5e5;
`;
const Header = styled.span`
font-size: 20px;
font-weight: 700;
`;
const HiddenHeader = styled.span`
font-size: 12px;
font-weight: 600;
display: ${props => (props.hiddenStatus ? "inline-block" : "none")};
animation: ${fadein} 0.3s;
`;
이미지 밖으로 마우스 포인터를 이동할 때 JavaScript를 실행한다
:hover
같은 CSS 동작을 적용하지 않는이유는?CSS동작은 스레드의 실행이 중지될 때마다 실행되기 때문에 속도가 느리다
그리고 :hover 동작은 IE6에서는 작동하지 않는다
HeaderBox 요소에
마우스포인터를 이동했을 때 showHiddenHeader() 함수를 실행하고
해당요소 밖으로 마우스포인터를 이동했을 때 hideHiddenHeader() 함수를 실행한다
HiddenHeader 요소의 기본 hiddenStatus 상태값은 false인데
HeaderBox 요소에 마우스포인터를 이동했을 때, showHiddenHeader()가 실행되면 ture로 바뀌고
HeaderBox 요소 밖으로 마우스 포인터가 이동했을 때, hideHiddenHeader()가 실행되면 다시 false로 바뀐다
여기서 hiddenStatus 변수는 HiddenHeader의 display속성값에 대해서 아래와 같이, 조건에 따라 보이거나 보이지 않게 설정할 때 쓰인다
display: ${props => (props.hiddenStatus ? "inline-block" : "none")};
hiddenStatus = false → display: none
hiddenStatus = true → display: nline-block
<Slider>
<LeftArrow onClick={handleLeftArrow}><</LeftArrow>
<CardWrapper curXAxis={curXAxis}>
{cardsData.map(card => {
return (
<Card
id={card.id}
img={card.thumb_nail}
onClick={handleModal}/>
);
})}
</CardWrapper>
<RightArrow onClick={handleRightArrow}>></RightArrow>
</Slider>
import Card from "./Card";
const handleLeftArrow = () => {
if (curXAxis < 0) {
setCurXAxis(curXAxis + imgWidth * 8);
}
};
const handleRightArrow = () => {
if (curXAxis > (totalCount - 8) * -imgWidth) {
setCurXAxis(curXAxis - imgWidth * 8);
}
};
const Slider = styled.div`
display: flex;
position: relative;
`;
const CardWrapper = styled.ul`
display: flex;
z-index: 0;
margin-left: 50px;
transform: translateX(${props => props.curXAxis}px);
transition: all 0.7s ease-in-out;
`;
const Arrow = styled.button`
position: absolute;
top: 100px;
direction: ${props => props.direction};
color: #e5e5e5;
opacity: 0.5;
font-size: 60px;
cursor: pointer;
z-index: 1;
&:hover {
opacity: 1;
}
`;
const LeftArrow = styled(Arrow.withComponent("button"))`
left: 0px;
`;
const RightArrow = styled(Arrow.withComponent("button"))`
right: 0px;
`;
<
: 특수문자 숫자표현이게 뭔지 몰라서 구글검색창에 <
이라고 검색하니까 <
이라고 검색된다
그래서 어떤건지 찾아봤는데 유니코드 특수문자 리스트 이러한 사이트에서
<
이라는 표현문자를 나타내는 숫자표현이었다
HTML 상에서 특수문자가 제대로 나타나지 않을 수 있기 때문에 아래 문자들를 사용한다고 한다
1) 새로운 styled-component를 생성하고 다른 태그에 적용시킨다
일단 이 코드를 먼저 보자면, Arrow라는 styled-component를 button태그에 적용했고
Arrow.withComponent("button")
2) CSS를 추가하고 싶으면 아래와 같이 styled()''
메서드를 사용하면 된다
styled(Arrow.withComponent("button"))`
left: 0px;
`;
그래서 아래의 LeftArrow, RightArrow 컴포넌트를 해석하자면
const LeftArrow = styled(Arrow.withComponent("button"))`
left: 0px;
`;
const RightArrow = styled(Arrow.withComponent("button"))`
right: 0px;
`;
Arrow 컴포넌트의 스타일속성을 button 태그에 입혀주고
각각 아래의 스타일 속성을 추가해줬다
LeftArrow 컴포넌트에는 left: 0px
RightArrow 컴포넌트에는 right: 0px
<LeftArrow onClick={handleLeftArrow}><</LeftArrow>
<RightArrow onClick={handleRightArrow}>></RightArrow>
const imgWidth = 180;
const totalCount = 21;
const handleLeftArrow = () => {
if (curXAxis < 0) {
setCurXAxis(curXAxis + imgWidth * 8);
}
};
const handleRightArrow = () => {
if (curXAxis > (totalCount - 8) * -imgWidth) {
setCurXAxis(curXAxis - imgWidth * 8);
}
};
LeftArrow 버튼을 눌렀을 때 발생하는 handleLeftArrow() 함수
: curXAxis가 0보다 작은 상태라면 이미지너비 * 8
만큼 더해주고
RightArrow 버튼을 눌렀을 때 발생하는 handleRightArrow() 함수
: curXAxis가 (totalCount - 8) * -imgWidth
보다 큰 상태라면 imgWidth * 8
만큼 빼준다
💡 질문하기!!
조건에 충족하지 않는 경우에는 어떻게 작동하는가??
- LeftArrow 버튼을 눌렀을 때 curXAxis가 0보다 크거나
- RightArrow 버튼을 눌렀을 때
(totalCount - 8) * -imgWidth
보다 작은 상태일 때- 어떤 로직으로 슬라이더가 작동하는건지...
<CardWrapper curXAxis={curXAxis}>
{cardsData.map(card => {
return (
<Card
id={card.id}
img={card.thumb_nail}
onClick={handleModal}/>
);
})}
</CardWrapper>
const [curXAxis, setCurXAxis] = useState(0);
const [cardsData, setCardsData] = useState([]);
const updateCardsData = data => {
setCardsData(data.Result);
};
const CardWrapper = styled.ul`
display: flex;
z-index: 0;
margin-left: 50px;
transform: translateX(${props => props.curXAxis}px);
transition: all 0.7s ease-in-out;
`;
curXAxis 변수에 따라 좌우로 이동하고
cardsData 배열의 요소를 map() 메서드를 이용해서 Card 컴포넌트를 반복해서 구현하는데
💡 handleFetch() 함수
초기값이 빈 배열인 cardsData의 상태를 변화시켜주는 setCardsData() 메서드는 handleFetch() 함수에서 사용되지만 이 부분도 더 공부할 필요가 있다...
handleFetch(`${MainAPI}/list?${paramsString}`, updateCardsData);
}, []);
Card 컴포넌트에 id, img, onClick이벤트 함수를 전달하는데
그 중에서 handleModal() 함수는
const [modalOn, setModalOn] = useState(false);
const handleModal = () => {
setModalOn(!modalOn);
};
기본적으로 false인 modalOn를
handleModal() 함수를 호출하게 되면 true로 바꾸고
그 상태에서 다시 handleModal() 함수를 호출하게 되면
원래 modalOn 상태인 false로 바뀌게 된다
<li>
<ImgBox
id={props.id}
src={props.img}
alt="imgbox"
onClick={props.onClick}
/>
</li>
const ImgBox = styled.img`
width: 200px;
height: 280px;
border-radius: 10px;
margin-left: 7px;
cursor: pointer;
&:hover {
transform: scale(1.1);
transition: transform 0.35s;
}
`;
props로 전달받은 id, img, onClick이벤트를 받은 img태그이다
const [modalOn, setModalOn] = useState(false);
<ModalPortal>
<Modal onClose={handleModal} modalOn={modalOn} />
</ModalPortal>
import ModalPortal from "../Components/Modal/Portal";
import Modal from "./Modal/Modal";
Portal.js 에서 불러온 ModalPortal 컴포넌트 내부에
Modal.js 에서 불러온 Modal 컴포넌트로 구성되어있다