๐Ÿค ์€์ง€log ๐Ÿค

[REACT] Pagination ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณธ๋ฌธ

๐Ÿ’™ React

[REACT] Pagination ๊ตฌํ˜„ํ•˜๊ธฐ

Eun_zii 2023. 8. 24. 16:18

 

 

 

// Main.tsx

import { useEffect, useState } from "react";
import styled from "styled-components";
import { useQuery } from "react-query";

import Pagination from "../templates/Pagination";

const Main = () => {
  // const [post, setPost] = useState([]);
  const [totalPosts, setTotalPosts] = useState(10); // ํŽ˜์ด์ง€ ๋‹น ๊ฒŒ์‹œ๋ฌผ ์ˆ˜
  const [page, setPage] = useState(1); // ํ˜„์žฌ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ
  const offset = (page - 1) * totalPosts; // ์ฒซ ๊ฒŒ์‹œ๋ฌผ์˜ ์œ„์น˜

  // useEffect(() => {
  //   fetch("https://jsonplaceholder.typicode.com/posts")
  //     .then((res) => res.json())
  //     .then((data) => setPosts(data));
  // }, []);

  const fetchPosts = async () => {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts");
    const data = await response.json();
    return data;
  };
  const { data: posts, isLoading } = useQuery("posts", fetchPosts);

  if (isLoading) return null;
  return (
    <Container>
      <Title> Pagination ๐Ÿ“Ž </Title>
      <select
        value={totalPosts}
        onChange={({ target: { value } }) => setTotalPosts(Number(value))}
      >
        <option value="10">10๊ฐœ์”ฉ ๋ณด๊ธฐ</option>
        <option value="20">20๊ฐœ์”ฉ ๋ณด๊ธฐ</option>
        <option value="30">30๊ฐœ์”ฉ ๋ณด๊ธฐ</option>
      </select>
      <div>
        {posts
          .slice(offset, offset + totalPosts)
          .map(({ id, title, body }: any) => (
            <div key={id}>
              <h3>
                {id}. {title}
              </h3>
              <p>{body}</p>
            </div>
          ))}
      </div>
      <Pagination
        total={posts.length}
        totalPosts={totalPosts}
        page={page}
        setPage={setPage}
      />
    </Container>
  );
};

const Container = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  select {
    margin: 20px auto;
    width: 120px;
    height: 30px;
    padding: 0 7px 0;
    border-radius: 5px;
  }
`;

const Title = styled.h2`
  font-size: 50px;
`;

export default Main;
// Pagination.tsx

import styled from "styled-components";

const Pagination = ({ total, totalPosts, page, setPage }: any) => {
  const numPages = Math.ceil(total / totalPosts);

  return (
    <Nav>
      <Button onClick={() => setPage(page - 1)} disabled={page === 1}>
        {"<"}
      </Button>
      {Array(numPages)
        .fill(1)
        .map((_, i) => (
          <Button key={i + 1} onClick={() => setPage(i + 1)}>
            {i + 1}
          </Button>
        ))}
      <Button onClick={() => setPage(page + 1)} disabled={page === numPages}>
        {">"}
      </Button>
    </Nav>
  );
};

const Nav = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 4px;
  margin: 16px;
`;

const Button = styled.button`
  border: none;
  background: #ffffff;
  color: #000000;
  font-size: 22px;
`;

export default Pagination;
728x90