728x90
드디어 페이지네이션 구현을 배웠다!!!!!!!!!!!
일단 내가 꾸며둔 마이페이지의 찜리스트 페이지(likepage)에서는
Table이라는 컴포넌트를 따로 만들어뒀고 , 그걸 Table컴포넌트를 가져다가 likepage안에서 사용했다.
일단 axios를 이용해서 데이터를 가져오자.
useEffect(()=>{
axios
.get(`${process.env.REACT_APP_API_URL}/members/favorite`, {
headers: {
"Content-Type": "application/json",
Authorization: localStorage.getItem("authToken"),
"ngrok-skip-browser-warning": "69420", //ngrok cors 에러
},
})
.then((res)=>{
//console.log(res.data.data);
setLikelist(res.data.data);
})
.catch((err)=> console.log(err));
}, []);
내가 쓸 데이터의 모습은 밑의 그림처럼 배열안에 객체가 있는 모습이다.
저걸 Likeitem으로 타입을 지정한다.
interface Likeitem {
titleKor: string,
price: number;
quantity: number;
capacity: number;
reviewRating: number;
}
const [likelist, setLikelist] = useState<Likeitem[]>([]);
이렇게 해서 저 데이터는 likelist가 된다.
likelist의 타입을 지정하자.
interface TableProps {
likelist: Likeitem[];
}
page가 가지고 있는 likelist를 Table로 내려줘야한다.
const Table = ({ likelist }: TableProps) => {
return (
<>
<StyledTable>
<thead>
<tr>
<StyledTh>
<input type="checkbox" />
</StyledTh>
<StyledTh>상품 목록</StyledTh>
<StyledTh>수 량(개)</StyledTh>
<StyledTh>가 격(원)</StyledTh>
</tr>
</thead>
<tbody>
{likelist.map((el: Likeitem, idx: number) => {
return (
<tr key={idx}>
<StyledTd>
<input type="checkbox" />
</StyledTd>
<StyledTd>{el.titleKor}</StyledTd>
<StyledTd>{el.quantity}</StyledTd>
<StyledTd>{el.price}</StyledTd>
</tr>
);
})}
</tbody>
</StyledTable>
</>
);
};
팀원이 만들어뒀던 pagination 컴포넌트에서
paginationProps내려주는걸 뭘 내리는지 보니까 얘네들이었다.
{ currentPage, setCurrentPage, itemsPerPage, totalData }
그럼 일단
likepage의 return 부분에 일단 저렇게 작성하자.
<Pagination currentPage={currentPage} setCurrentPage={setCurrentPage}
itemsPerPage={itemsPerPage} totalData={totalData} />
이제 페이지네이션 기능에 대해서 생각해보자.
const [totalLength, setTotalLength] = useState<number>(0);
const [currentPage, setCurrentPage} = useState<number>(1);
//totalLength: 전체 길이
//currentPage: 첫번째페이지
//나오는 총 페이지수
const totalPages = Math.ceil(totalLength / 5);
//한페이지에 나오는 데이터를 쪼개는거다.
const paginationData = likelist.slice(5*(currentPage - 1), 5*currentPage);
이제 return 부분에서 정리하면 된다.
먼저 Table에 slice로 나눈 데이터를 표시한다.
<Table likelist={paginationData}></Table>
그리고 아까 위에서 적혀있던 코드를 정리하자.
<Pagination currentPage={currentPage} setCurrentPage={setCurrentPage}
itemsPerPage={itemsPerPage} totalData={totalData} />
위에서 저렇게 적혀있던 코드를 수정하자.
<Pagination currentPage={currentPage} setCurrentPage={setCurrentPage}
itemsPerPage={5} totalData={15} />
처음 뜨는 페이지가 1이니까 currentPage를 1로
각페이지당 5개씩 뜨게 할거니까 itemsPerPage를 5
전체 데이터 수가 15니까 totalData를 15로
//likepage.tsx
//마이페이지의 첫화면, 찜리스트 페이지
//grid 활용하는거 생각해보기!!!!
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import axios from "axios";
import { ButtonDark } from "../../components/Common/Button";
import Pagination from "../../components/AlcoholPage/Pagination";
//components
interface Likeitem {
titleKor: string;
price: number;
quantity: number;
capacity: number;
reviewRating: number;
}
//page에서 table로 내린애
interface TableProps {
likelist: Likeitem[];
}
const TotalStyled = styled.div`
display: flex;
justify-content: center;
align-items: center;
background-color: #f7f7f7;
`;
const LikepageContainer = styled.div`
/* border: 5px solid blue; */
width: 100vw;
height: 100vh;
max-width: 1250px;
margin-top: 150px; //호버됬을때가 150이래서 일단 150으로 설정함.
display: flex;
flex-direction: column;
`;
//누구누구님 등급써있는부분
const LikepageHeadStyled = styled.div`
/* border: 3px solid black; */
flex-grow: 3;
font-size: 18px;
display: flex;
flex-direction: column;
justify-content: center;
background-color: #dedede;
> p {
margin-left: 10px;
margin-bottom: 10px;
color: #181818;
font-weight: 600;
}
`;
//찜리스트 나오는 부분
const LikepageMainStyled = styled.div`
/* border: 3px solid red; */
flex-grow: 7;
> * {
margin-bottom: 30px;
font-size: 18px;
/* margin-left: 60px; */
}
> p {
margin-top: 30px;
font-weight: 600;
margin-left: 60px;
}
`;
//선택상품 장바구니, 삭제 버튼
const LikeBtnStyled = styled.div`
margin-top: 20px;
margin-right: 37px;
display: flex;
flex-direction: row;
float: right;
gap: 37px;
height: 52px;
border-radius: 7px;
> button {
background-color: #222222;
color: whitesmoke;
}
`;
const StyledTable = styled.table`
border: 1px solid black;
font-size: 18px;
margin-top: 200px;
width: 1240px;
height: 300px;
`;
const StyledTh = styled.th`
border: 1px solid black;
padding: 8px;
`;
const StyledTd = styled.td`
border: 1px solid black;
padding: 8px;
text-align: center;
vertical-align: middle;
`;
//맨밑 페이지네이션부분
const PigStyled = styled.div`
border: 1px solid red;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Table = ({ likelist }: TableProps) => {
return (
<>
<StyledTable>
<thead>
<tr>
<StyledTh>
<input type="checkbox" />
</StyledTh>
<StyledTh>상품 목록</StyledTh>
<StyledTh>수 량(개)</StyledTh>
<StyledTh>가 격(원)</StyledTh>
</tr>
</thead>
<tbody>
{likelist.map((el: Likeitem, idx: number) => {
return (
<tr key={idx}>
<StyledTd>
<input type="checkbox" />
</StyledTd>
<StyledTd>{el.titleKor}</StyledTd>
<StyledTd>{el.quantity}</StyledTd>
<StyledTd>{el.price}</StyledTd>
</tr>
);
})}
</tbody>
</StyledTable>
</>
);
};
const Likepage = () => {
const [likelist, setLikelist] = useState<Likeitem[]>([]);
const [totalLength, setTotalLength] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
const navigate = useNavigate();
//나오는 총 페이지수
const totalPages = Math.ceil(totalLength / 5);
const paginationData = likelist.slice(5 * (currentPage - 1), 5 * currentPage);
// console.log(currentPage);
useEffect(() => {
axios
.get(`${process.env.REACT_APP_API_URL}/members/favorite`, {
headers: {
"Content-Type": "application/json",
Authorization: localStorage.getItem("authToken"),
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => {
// console.log(res);
// console.log(res.data.data);
setLikelist(res.data.data);
// console.log(res.data.data.length);
setTotalLength(res.data.data.length);
})
.catch((err) => console.log(err));
}, []);
return (
<>
<TotalStyled>
<LikepageContainer>
<LikepageHeadStyled>
<p>찐영이야님의 등급은 Green입니다.</p>
</LikepageHeadStyled>
<LikepageMainStyled>
<p>찜리스트</p>
<LikeBtnStyled>
<ButtonDark width="150px" height="100%" onClick={() => navigate("/mypage/likepage")}>
선택상품 장바구니
</ButtonDark>
{/* <button>선택상품 장바구니</button> */}
{/* 아무주소나 이동하게 해둠 */}
<ButtonDark width="150px" height="100%" onClick={() => navigate("/mypage/likepage")}>
선택상품 삭제
</ButtonDark>
</LikeBtnStyled>
<Table likelist={paginationData}></Table>
</LikepageMainStyled>
<PigStyled>
<Pagination currentPage={currentPage} setCurrentPage={setCurrentPage} itemsPerPage={5} totalData={15} />
</PigStyled>
</LikepageContainer>
</TotalStyled>
</>
);
};
export default Likepage;
//Pagination.tsx
import React from "react";
import styled from "styled-components";
import { PaginationProps } from "../../types/AlcholInterfaces";
const PaginationContainer = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 5rem;
`;
const StyledPaginationBtn = styled.button`
width: 30px;
height: 40px;
margin: 0 4px;
padding: 7px 10px;
border: 1px solid #dee2e6;
border-radius: 4px;
cursor: pointer;
background-color: #f8f9fa;
color: #495057;
font-size: 14px;
transition: background-color 0.2s;
&:hover {
background-color: #e9ecef;
}
&:disabled {
cursor: not-allowed;
color: #fff;
background: #a84448;
}
`;
const Pagination: React.FC<PaginationProps> = ({ currentPage, setCurrentPage, itemsPerPage, totalData }) => {
const totalPgaes = Math.ceil(totalData / itemsPerPage);
const handleClickPage = (pageNum: number): void => {
setCurrentPage(pageNum);
window.scrollTo(0, 0);
};
// 페이지네이션 버튼들
const PaginationBtns = () => {
const btns = [];
for (let i = 1; i <= totalPgaes; i++) {
btns.push(
<StyledPaginationBtn key={i} onClick={() => handleClickPage(i)} disabled={currentPage === i}>
{i}
</StyledPaginationBtn>,
);
}
return btns;
};
return <PaginationContainer>{PaginationBtns()}</PaginationContainer>;
};
export default Pagination;
//Interfaces.ts
// 주류 리스트 데이터
export interface AlcoholListData {
itemId: number;
titleKor: string;
discountRate: number;
price: number;
categories: string[];
profile: string;
reviewCount: number;
reviewRating: number;
}
// 주류 리스트 데이터 Props
export interface AlcoholListProps {
data: AlcoholListData[] | null;
totalData: number;
currentPage: number;
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
size: number;
}
// 주류 리스트 상세 데이터
// export interface AlcoholData {
// }
// 페이지네이션 Props
export interface PaginationProps {
currentPage: number;
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
itemsPerPage: number;
totalData: number;
}
728x90
'개인공부 > 메인프로젝트' 카테고리의 다른 글
카카오맵이용 - 사용자 현재위치조회 (0) | 2023.05.16 |
---|---|
카카오 지도 연결하기 (0) | 2023.05.14 |
오늘도 윈도우는 멍청했던건가......... (0) | 2023.05.10 |
개발자에게는 맥북이 답인가보다..... (0) | 2023.05.08 |
0508 메인플젝 (0) | 2023.05.08 |