[React] 더보기 버튼

    반응형

    🫧 예시

    - 초기에 5개의 항목씩 보여주고 더보기 버튼을 누르면 다음 항목을 보여주는 기능으로 더이상 보여줄 데이터가 없다면 더보기 버튼은 사라짐


    🫧 필요한 값 설정

      const [reviewList, setReviewList] = useState([]); // 리뷰 목록
      const pageSize = useRef(5); // 보여줄 목록 수
      const [totalPage, setTotalPage] = useState(); // 총 페이지
      const [currentPage, setCurrentPage] = useState(1); // 현재 페이지

    꼭 필요한 값은 4가지이다.

    ① 보여줄 데이터의 값

    ② 한 페이지의 보여주고 싶은 목록의 수 (한 페이지당 보여줄 값은 고정값이므로 useRef를 사용함)

    ③ 목록의 총 페이지 수

    ④ 현재 페이지 수로 초기값을 1로 설정


    🫧 값에 데이터 넣기

      useEffect(() => {
        studyReviewList(stdId, revewListSuccess, currentPage, pageSize.current);
      }, [currentPage]);

    서버에서 값을 받아왔는데, useEffect를 사용하여 currentPage가 바뀔 때마다 서버에서 값을 받아오게 설정하였다.

    서버에서는 현재의 페이지와 보여줄 목록 수를 가지고 list로 값을 준다.

    (pazeSize는 useRef를 사용했으므로 꼭 pageSize.current를 이용하여 값을 가져와야 한다.)

     

      const revewListSuccess = (res) => {
        setReviewList(reviewList.concat(res.data.list));
        setTotalPage(res.data.list[0].totCnt);
      };

    받아온 값을 setReviewList 에 저장하고 원래의 concat을 사용하여 원래의 있던 배열과 합쳐준다.

    예를 들어서, 원래 있던 값이 [1,2]고, 서버에서 새로 받아온 값이 [3,4,5]라고 하면

    concat으로 새로운 배열인 [1,2,3,4,5]로 값을 설정하는 것이다.

    그리고 setTotalPage 에 전체 총 목록의 수를 저장한다.

     

    ➡️ 정리

     currentPage가 바뀔 때마다 서버에 값을 받아와서 새로운 list로 업데이트를 해줌


    🫧 버튼 누를 때마다 새로운 데이터 받기

      {totalPage > pageSize.current * currentPage && (
        <MediumButton
          text={"더보기"}
          type={"PurpleWhite"}
          style={{ width: "200px", display: "block", margin: "20px auto" }}
          onClick={nextPageHandler}
        />
      )}

    버튼을 전체 페이지에서 보여줄 값이 있을 때만 보여주게 설정을 하고,
    (전체 페이지 > 한 페이지 당 모여줄 목록 수 * 현재 페이지 수)

    이벤트 핸들러를 만들어 준다.

     

      const nextPageHandler = () => {
        setCurrentPage(currentPage + 1);
      };

    이벤트 핸들러는 클릭할 때마다 currentPage의 값을 1씩 증가시켜 준다.


    🫧 최종코드

    "use client";
    
    import { useContext, useEffect, useRef, useState } from "react";
    import { StudyInfoContext } from "../layout";
    import { noDataList } from "@/app/common/Util";
    import { MediumButton } from "@/app/common/Button";
    import { studyReviewList } from "@/app/apis/studyAPI";
    import ReviewElement from "../components/ReviewElement";
    
    // 스터디 활동하기 > 스터디 리뷰 페이지
    function Review() {
      const { stdId } = useContext(StudyInfoContext);
    
      const [reviewList, setReviewList] = useState([]); // 리뷰 목록
      const pageSize = useRef(5); // 보여줄 목록 수
      const [totalPage, setTotalPage] = useState(); // 총 페이지
      const [currentPage, setCurrentPage] = useState(1); // 현재 페이지
    
      useEffect(() => {
        studyReviewList(stdId, revewListSuccess, currentPage, pageSize.current);
      }, [currentPage]);
    
      const revewListSuccess = (res) => {
        setReviewList(reviewList.concat(res.data.list));
        setTotalPage(res.data.list[0].totCnt);
      };
    
      // 더보기 버튼
      const nextPageHandler = () => {
        setCurrentPage(currentPage + 1);
      };
    
      return (
        <>
          {reviewList && (
            <div style={{ margin: "0 15%" }}>
              {noDataList(
                reviewList,
                reviewList &&
                  reviewList.map((item) => {
                    return <ReviewElement key={item.revId} detail={item} />;
                  })
              )}
              {totalPage > pageSize.current * currentPage && (
                <MediumButton
                  text={"더보기"}
                  type={"PurpleWhite"}
                  style={{ width: "200px", display: "block", margin: "20px auto" }}
                  onClick={nextPageHandler}
                />
              )}
            </div>
          )}
        </>
      );
    }
    
    export default Review;

    실행화면 -  더이상 보여줄 값이 없다면 '더보기'버튼이 사라짐

    반응형

    댓글