[Pre-Project] 지식 정리

0
post-thumbnail

📌 페이지 네이션 구현

글 목록을 불러와서 한 페이지당 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);
      });
  }, []); 

0개의 댓글