[React] 미리 만들어둔 여러 개의 템플릿에 내용물을 동적으로 배분하기
2024. 1. 5. 01:34
반응형
구현해야하는 조건
- api response로 받아온 책이 몇 권이냐에 따라 carousel 한 페이지에서 렌더링되어야 하는 책의 개수와 순서가 정해져있음
- carousel 1페이지에 들어가는 책은 최소 1권, 최대 5권
- 5권(캐러솔 한페이지당) * 총 4페이지 = 20권까지는 위 템플릿대로 들어가고, 21권째부터 carousel 1번으로 돌아가서 반복(사용자가 등록한 책의 권 수는 무한대로 늘어날 수 있음)
하나의 템플릿에 데이터를 mapping 하는 것을 넘어, 어떻게 4개의 템플릿에 동적으로 분배해서 렌더링할지 고민했다.
api 데이터 불러오는 컴포넌트
1. 일단 한 페이지당 5권씩 들어가도록 데이터를 나눠준다.
2. 1번에서 나눠진 데이터를 다시 맵핑하여 한 페이지당 들어갈 정보로 가공한다.
3. 캐러솔 페이지의 props로 넘겨준다.
// 한 페이지당 5권씩 들어가도록 array 나누기
const slicedBookList = useMemo((): BookType[][] => {
const books = data?.data ?? []
let result = []
for (let i = 0; i < books.length; i += 5) {
result.push(books.slice(i, i + 5))
}
return result
}, [data?.data])
const pageData = slicedBookList.map((books, index) => {
return { id: index, pageIndex: index % 4, bookList: books }
})
...
return (
<Carousel
showIndicators={false}
showArrows={false}
showStatus={false}
infiniteLoop={true}
emulateTouch={true}
>
{pageData.map((page) => {
return (
<CarouselPage
key={page.id}
pageIndex={page.pageIndex}
bookList={page.bookList}
/>
)
})}
</Carousel>
)
CarouselPage.tsx
1. 미리 퍼블리싱해둔 템플릿들을 2차원 배열에 담아주고
2. pageIndex(전체 캐러솔 중 몇번째 페이지인지), bookIndex(특정 캐러솔의 몇 번째 책인지)에 따라 렌더링해준다.
const covers = [
[Page0Book0, Page0Book1, Page0Book2, Page0Book3, Page0Book4],
[Page1Book0, Page1Book1, Page1Book2, Page1Book3, Page1Book4],
[Page2Book0, Page2Book1, Page2Book2, Page2Book3, Page2Book4],
[Page3Book0, Page3Book1, Page3Book2, Page3Book3, Page3Book4],
]
...
return(
<div>
{bookList.map((book, bookIndex) => {
// 내용물이 어느 템플릿과 어느 위치에 들어갈지 유동적으로 정해주기
const Templete = covers[pageIndex][bookIndex]
return (
<Templete key={bookIndex} onClick={() => handleSelectBook(book)}>
<Typo>{book.title}</Typo>
</Templete>
)
})}
</div>
)
반응형
'한 걸음 > React & Next.js' 카테고리의 다른 글
[React + Vite + styled-components] npm 배포 후 ThemeProvider를 인식하지 못할 때 (0) | 2024.01.09 |
---|---|
[vite+storybook] 스토리북 argTypes 명확하게 표기하기 (0) | 2024.01.05 |
[vite + typescript + pnpm] npm publish 후 다른 프로젝트에서 install 했을 때, 모듈을 찾을 수 없다는 에러 (1) | 2024.01.03 |
[React] form submit 버튼이 form 바깥에 위치해야 하는 경우 (1) | 2023.12.07 |
[React] useMemo 사용으로 인한 삽질기 (1) | 2023.12.07 |