글 목록을 불러와서 한 페이지당 15개씩 목록을 보여주고 다음페이지로 넘어가게끔 페이지네이션 구현
Array.from () : 반복 가능하거나 배열과 같은 객체에서 얕은 복사로 새 인스턴스를 만듬
[예시]console.log(Array.from([1, 2, 3], (x) => x + x)); // Expected output: Array [2, 4, 6]
export default function QuestionListPage() {
// 질문 목록 저장
const [questions, setQuestions] = useState([]);
// 현재 페이지와 페이지당 아이템 수를 나타내는 상태 설정
const [currentPage, setCurrentPage] = useState(1);
// 각 페이지에 표시될 아이템의 수
const itemsPerPage = 15;
useEffect(() => {
fetch(`http://13.124.105.17:8080/questions`)
.then((res) => res.json())
.then((json) => {
setQuestions(json);
console.log(json);
});
}, []); // 첫렌더링시에만 api호출이 되게 빈 배열을 넣어줌
// 페이지 번호를 변경할 때마다 호툴되는 핸들러 함수
const handlePageChange = (newPage) => {
setCurrentPage(newPage);
};
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
// 현재 페이지의 데이터만 추출
const visibleQuestions = questions.slice(startIndex, endIndex);
// 전체 페이지수를 계산해줌
// Math.ceil은 전체 데이터의 개수를 itemperpage로 나눈 후 올림하여 전체 페이지 수를 구함
const totalPages = Math.ceil(questions.length / itemsPerPage);
const pageNumbers = Array.from(
// totalpage만큼의 길이를 가진 배열을 생성
{ length: totalPages },
// '_' 무시되는 값, index : 현재 반복 인덱스를 나타냄(해당 인덱스를 기반으로 각 페이지 번호를 생성)
// index = 0부터 시작이고 + 1을 해주는 이유는 페이지번호가 1부터 시작하기 때문
(_, index) => index + 1,
);
// 페이지 번호 버튼을 생성하고 클릭 이벤트를 통해 페이지를 변경할 수 있게 구현됨
const renderPageNumbers = pageNumbers.map((number) => (
// key : 각 버튼을 구별하기 위한 고유의 키
<Button key={number} onClick={() => handlePageChange(number)}>
{number}
</Button>
));
return (
<>
<Header />
<QuestionPage>
<div className="main_container">
<div className="main_header">
<h1>All Question </h1>
<button className="qa_btn">Ask Question</button>
</div>
<div className="main_question_filer">
<div className="question_item">{questions.length} questions</div>
<div className="question_filters">
<div className="question_filters_item">
{/* 버튼 클릭시 필터 기능이용해서 구현 진행 */}
<Button className="question_filter_newest" leftRadius>
Newest
</Button>
<Button className="question_filter_active">Active</Button>
<Button className="question_filter_bountied">Bountied</Button>
<Button className="question_filter_unanswered">
Unanswerd
</Button>
<Button className="question_filter_more" rightRadius>
More
</Button>
{/* 버튼을 누르면 모달이 dropdown되면서 뜨게 구현 */}
</div>
<button className="select_filter_contatiner">
<FontAwesomeIcon
icon={faArrowDownWideShort}
className="select_filter_icon"
/>
<div className="select_filer_text">Filter</div>
</button>
</div>
</div>
<div className="main_questions">
{visibleQuestions.map((question, idx) => (
<Question question={question} key={idx} />
))}
</div>
<div className="pagination">{renderPageNumbers}</div>
</div>
</QuestionPage>
</>
);
}
글이 업데이트 되면 최신 등록글이 제일 상단에 뜨게끔 구현
sort 함수 : sort 함수내에서 2개의 인자의 비교값을 비교해준다(b-a=양수일경우 b가 더 최신이기에 상단에 옴)
[예시]const sortedQuestions = json.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
useEffect(() => {
fetch(`http://13.124.105.17:8080/questions`)
.then((res) => res.json())
.then((json) => {
// 날짜입력순으로 최신글이 위로 보이게 구현
const sortedQuestions = json.sort(
(a, b) => new Date(b.createdAt) - new Date(a.createdAt),
);
setQuestions(sortedQuestions);
setCurrentPage(1);
});
}, []);