[블록카] Docs
by 한만섭
1. MainPage
Main은 블록카 프로젝트의 시작 페이지입니다. Main페이지에는 아래와 같은 컴포넌트들을 사용합니다. 저는 styled-components를 사용했기 때문에 styled-component로 만든 컴포넌트도 아래에 포함시키도록 하겠습니다.
아래의 두 컴포넌트는 모든 페이지에 공통적으로 사용될 컴포넌트이기 때문에 Router바깥에 선언하도록하겠습니다.
- Header
- SideBar
Router.tsx
(...중략...)
export default () => {
return (
<>
<Header />
<Sidebar></Sidebar>
<Router>
<Switch>
<Route path="/" exact component={Main}></Route>
<Route path="/search" exact component={Search}></Route>
<Route path="/sellcar" exact component={SellCar}></Route>
<Route path="/buycar" exact component={BuyCar}></Route>
<Route path="/search/:id" exact component={CarDetail}></Route>
<Redirect from="*" to="/"></Redirect>
</Switch>
</Router>
<Footer></Footer>
</>
);
};
이제는 모든 페이지에 공통으로 들어가는 컴포넌트가 아닌 Main페이지에만 들어가는 컴포넌트를 작성하겠습니다.
- MainBanner
- SearchCarContainer
- SearchForm
- SearchPreFilterList
- PreFilterItem
- FilterTitle
- FilterContent
- PreFilterItem
- ButtonContainer
- Button (검색)
- Button (취소)
- LatestRegisteredCarListContainer
- LatestRegisteredCarListHeader
- FatText (최근 등록 차량)
- LatestRegisteredCarList
- CarCard
- LatestRegisteredCarListHeader
- Footer
위와 같은 구조로 설계하면 아래와 같은 사이트 형태를 나타내게 됩니다.
1.1 MainBanner
메인 페이지에 사용될 슬라이드배너의 구조에 대해 정리하겠습니다. MainBanner에서 사용하는 컴포넌트는 아래와 같습니다.
-
Wrapper
- ImageListContainer
- Image
- LeftButtonContainer
- LeftIcon
- RightButtonContainer
- RightIcon
- ImageListContainer
위와 같은 구조로 설계하면 아래와 같은 형태가 됩니다.
실제 MainBanner는 이미지가 일정 시간 마다 Slide되어야 합니다. 해당 부분 코드를 보여드리겠습니다.
MainBanner.tsx
interface IImageListContainerProps {
moveSize: string;
length: number;
selectedImage: number;
}
const ImageListContainer = styled.div<IImageListContainerProps>`
display: grid;
transition: all ${props => (props.selectedImage === 0 ? "0s" : "1s")}
ease-in-out;
transform: translateX(-${props => props.selectedImage * 100}vw);
grid-template-columns: ${props =>
`repeat(${props.length},${props.moveSize});`};
`;
props로 selectedImage(현재 선택된 이미지)를 넘겨받아서 선택된 이미지 만큼 아래 코드를 사용해 이동시켜줍니다.
transform: translateX(-${props => props.selectedImage * 100}vw);
그러면 selectedImage를 일정 시간마다 변경시켜주는 부분이 필요합니다. 그 부분은 아래 코드에서 확인하실 수 있습니다.
MainBanner.tsx
(...중략...)
const moveSize = "100vw";
const slideInterval = 4000;
const slide = () => {
if (selectedImage == images.length - 1) {
setTimeout(() => {
setSelectedImage(0);
}, slideInterval);
} else {
setTimeout(() => {
setSelectedImage(selectedImage + 1);
}, slideInterval);
}
};
useEffect(() => {
slide();
});
(...중략...)
위의 코드는 리액트의 라이프 사이클을 이용해서 반복동작을 하도록 구현한 것입니다. 먼저 보아야할 곳은 useEffect입니다.
useEffect(() => {
slide();
});
위 처럼 작성하게 되면 ComponentDidMount , ComponentDidUpdate를 하게 될 때 slide를 호출해줍니다. 그럼 이제 slide함수를 보겠습니다. slide함수는 selectedImage를 1씩 증가 시키고, selectedImage가 이미지 갯수 만큼 증가했으면 0으로 바꿔줘서 0 –> 1–> 2 –> 3 –> 0과 같은 형태로 selectedImage를 set해줍니다.
const slide = () => {
if (selectedImage == images.length - 1) {
setTimeout(() => {
setSelectedImage(0);
}, slideInterval);
} else {
setTimeout(() => {
setSelectedImage(selectedImage + 1);
}, slideInterval);
}
};
근데 여기서 중요한 점은 useState의 set함수를 호출하게 되면 rerender를 하게됩니다. reRendering을 한다는 것은 ComponentDidUpdate를 호출하게 되고 그렇게 될 경우
useEffect(() => {
slide();
});
useEffect를 통해 slide가 다시 호출됩니다. 결국 재귀와 비슷한 형태로 계속해서 이미지가 변경되게 됩니다.
간략히 말해서,
- 컴포넌트가 생성됨
- slide 호출
- slide에서 setState호출
- 컴포넌트 reRendering
- ComponentDidUpdate 호출
- UseEffect를 통해 slide 재 호출 (2번으로 돌아감)
위와 같은 동작을 계속해서 하는 것입니다.
이렇게 component의 라이프사이클을 사용해서 이미지가 계속 슬라이드 되는 컴포넌트를 구현할 수 있습니다.
Subscribe via RSS