React의 페이지네이션

28640 단어 javascriptreactwebdev
웹사이트를 디자인하는 동안 우리는 사용자가 적절하게 데이터를 사용할 수 있고 데이터에 압도되지 않도록 데이터를 표시하는 방법에 대해 생각해야 합니다. 데이터가 체계화될수록 웹 사이트의 사용자 경험이 향상됩니다.

페이지네이션은 이를 달성하기 위한 그러한 방법 중 하나입니다. 웹 콘텐츠를 별도의 페이지로 나누어 제한적이고 소화 가능한 방식으로 콘텐츠를 표시하는 방법입니다.

이 블로그에서는 이https://jsonplaceholder.typicode.com/posts API에서 데이터를 가져와 페이지 매김 형식으로 표시하는 간단한 반응 앱을 만들 것입니다.

여기에서는 모든 데이터를 한 번에 가져온 다음 페이지에 표시하지만 백엔드를 사용하면 각 페이지에 대한 작은 데이터 청크를 가져올 수 있으며 두 방법에 대한 프런트엔드 페이지 매김 코드는 동일하게 유지됩니다.
  • Setting up files
  • Writing code to fetch data
  • Writing the Pagination Component
  • Putting the whole code together

  • 시작하자!

    1. 파일 설정

    Create a react app by using the create react app template

    npx create-react-app pagination-app
    

    or you can also code on codesandbox or stackblitz

    After the app is created, your folder structure might look like this

    2. 데이터를 가져오는 코드 작성

    We will use the fetch API to get the data from the jsonplaceholder API and store it in a state. Remove all the code from your App.js file and write the code given below

    import { useState } from "react";
    
    const URL = "https://jsonplaceholder.typicode.com/posts";
    
    function App() {
      const [posts, setPosts] = useState([]);
      useEffect(() => {
        fetch(URL)
          .then((response) => {
            if (response.ok) return response.json();
            throw new Error("could not fetch posts");
          })
          .then((posts) => setPosts(posts))
          .catch((error) => console.error(error));
      },[]);
      return <div className="App"></div>;
    }
    
    export default App;
    

    Here, we have written the fetch function inside useEffect hook and passed an empty dependency array, this will make sure that our fetch function runs only once, after the page is loaded. If the data is fetched successfully, it will be stored in the state, else the error will be displayed in the console.

    If you wish to understand more about how fetch works, you can read my blog

    3. 페이지네이션 컴포넌트 작성하기

    Now, after getting the data, we will write our Pagination Component.

    Create a file Pagination.js in your src folder.
    We will display 5 posts per page, and that will be our page limit. We will store the current page number in a state and update it using the Previous and Next button, also we will display 3 consecutive page numbers, viz previous, current and next.

    import React, { useState, useEffect } from "react";
    
    const Pagination = ({ pageDataLimit, posts }) => {
      const [currPageNo, setCurrPageNo] = useState(1);
      const [currPagePosts, setCurrPagePosts] = useState([]);
      const [pageNumberGroup, setPageNumberGroup] = useState([]);
    
      useEffect(() => {
        setCurrPagePosts(getPageData());
        setPageNumberGroup(getPageNumberGroup());
        console.log("run");
      }, [posts, currPageNo]);
    
      const nextPage = () => setCurrPageNo((prev) => prev + 1);
      const previousPage = () => setCurrPageNo((prev) => prev - 1);
      const changePageTo = (pageNumber) => setCurrPageNo(pageNumber);
      const getPageData = () => {
        const startIndex = currPageNo * pageDataLimit - pageDataLimit;
        const endIndex = startIndex + pageDataLimit;
        return posts.slice(startIndex, endIndex);
      };
       const getPageNumberGroup = () => {
        let start = Math.floor((currPageNo - 1) / 3) * 3;
        console.log(new Array(3).fill(" ").map((_, index) => start + index + 1));
        return new Array(3).fill(" ").map((_, index) => start + index + 1);
      };
    return (
        <div></div>
      );
    };
    
    export { Pagination };
    
    

    Here, our pagination component is getting posts and page limit as props. The getPageData funtion will be used to calculate the posts to be shown in each page. Using the start and end index we will slice the posts array and update the currPagePosts state.
    The getPageNumberGroup function is used to display the previous, current and the next page numbers.

    Now, we will map over the currPagePosts and pageNumberGroup states to display the posts.

    return (
        <div>
          <h1 className="heading">Posts in Pagination</h1>
          <ul className="posts-container list-style-none">
            {currPagePosts.map(({ id, title, body }) => {
              return (
                <li key={id} className="post">
                  <h3>{title}</h3>
                  <p>{body}</p>
                </li>
              );
            })}
          </ul>
          <div className="page-num-container">
            <button
              className={`page-change-btn ${currPageNo === 1 ? "disabled" : ""}  `}
              disabled={currPageNo === 1}
              onClick={previousPage}
            >
              Previous
            </button>
            <ul className="page-num-container list-style-none">
              {pageNumberGroup.map((value, index) => {
                return (
                  <li
                    className={`page-number ${
                      currPageNo === value ? "active" : ""
                    } `}
                    key={index}
                    onClick={() => changePageTo(value)}
                  >
                    {value}
                  </li>
                );
              })}
            </ul>
            <button
              disabled={currPageNo === Math.floor(posts.length / pageDataLimit)}
              className={`page-change-btn ${
                currPageNo === Math.floor(posts.length / pageDataLimit)
                  ? "disabled"
                  : ""
              }  `}
              onClick={nextPage}
            >
              Next
            </button>
          </div>
        </div>
    

    We are first displaying all the posts, below that the page numbers along with the buttons. The previous button will be disabled when we are on the first page and similarly the next button will be disabled when we are at the last page.

    Below are the styles for the pagination component. Write the code in App.css file and import it in Pagination.js file.

    .heading {
      text-align: center;
      margin: 1rem;
    }
    
    .posts-container {
      display: grid;
      grid-template-columns: 18rem 18rem 18rem;
      gap: 1rem;
      align-items: stretch;
      justify-content: center;
    }
    
    .post {
      max-width: 16rem;
      text-align: center;
      padding: 1rem;
      margin: 0.5rem;
      color: "#c4c4c4";
      border: 1px solid purple;
      border-radius: 0.25rem;
    }
    
    .page-num-container {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .page-change-btn {
      padding: 0.5rem 1rem;
      margin: 0 0.5rem;
      border: none;
      border-radius: 0.25rem;
      outline: none;
      background-color: purple;
      color: white;
      cursor: pointer;
    }
    
    .disabled {
      cursor: not-allowed;
      background-color: gray;
    }
    
    .page-number {
      border: 1px solid grey;
      border-radius: 50%;
      width: 2rem;
      height: 2rem;
      line-height: 2rem;
      text-align: center;
      margin: 0 0.25rem;
      cursor: pointer;
    }
    
    .active {
      border-color: purple;
    }
    
    .list-style-none {
      list-style: none;
      padding-inline-start: 0;
    }
    
    

    4. 전체 코드 통합

    We have our Pagination component ready, now we just need to call the component in App.js file.

     <div className="App">
        <Pagination pageDataLimit={5} posts={posts} />
     </div>
    

    Once you have written all the code, run

    npm start
    
    The whole code and demo is uploaded on github .
    행복한 코딩!

    좋은 웹페이지 즐겨찾기