🀍 은지log 🀍

[REACT] Pagination κ³Ό Querystring λ³Έλ¬Έ

πŸ’™ React

[REACT] Pagination κ³Ό Querystring

Eun_zii 2022. 10. 6. 13:55

 

 

Naver μ˜ν™” 검색

🎣 1. Router.js 생성 import { BrowserRouter, Routes, Route } from 'react-router-dom' import Main from './components/pages/Main' import Movie from './components/pages/Movie' import Book from './comp..

eun-jii.tistory.com

 

 

Naver μ±… 검색

Naver μ˜ν™” 검색 🎣 1. Router.js 생성 import { BrowserRouter, Routes, Route } from 'react-router-dom' import Main from './components/pages/Main' import Movie from './components/pages/Movie' import Bo..

eun-jii.tistory.com

 

 

 

🎣 Pagination.jsx 생성

import styled from 'styled-components'

const Pagination = ({ nowPage, total, onPageChange }) => {
  const lastPage = Math.ceil(total / 10)
  const startPage = Math.ceil(nowPage / 10) * 10 - 9
  const endPage = startPage + 9 > lastPage ? lastPage : startPage + 9

  const pageList = []
  for (let i = startPage; i <= endPage; i++) {
    pageList.push(i)
  }
  return (
    <List>
      {nowPage > 1 && (
        <Page onClick={() => onPageChange(nowPage - 1)}>{'<'}</Page>
      )}
      {pageList.map((page) => (
        <Page
          isActive={page === nowPage}
          key={page}
          onClick={() => onPageChange(page)}
        >
          {page}
        </Page>
      ))}
      {nowPage < lastPage && (
        <Page onClick={() => onPageChange(nowPage + 1)}>{'>'}</Page>
      )}
    </List>
  )
}

const List = styled.div`
  display: flex;
  justify-content: center;
`
const Page = styled.button`
  background: ${({ isActive }) => isActive && '#000'};
  color: ${({ isActive }) => isActive && '#fff'};
`

export default Pagination

🎣 Movie.jsx

import { useEffect, useState } from 'react'
import styled from 'styled-components'
import { getMovieList } from '../../apis'
import MovieList from '../organisms/MovieList'
import { countryList, genreList } from '../../datas'
import Pagination from '../organisms/Pagination'

const Movie = () => {
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [text, setText] = useState('')
  const [country, setCountry] = useState('ALL')
  const [genre, setGenre] = useState('ALL')
  const [movieList, setMovieList] = useState([])

  useEffect(() => {
    searchMovieList()
  }, [country, genre, page])

  const handleSubmit = async (e) => {
    e.preventDefault()
    setPage(1)

    searchMovieList()
  }
  const searchMovieList = async () => {
    if (text === '') return
    // const params = { query: text, country }
    // if(country === "ALL") delete params.country;

    const start = page * 10 - 9

    const params = { query: text, start }
    if (country !== 'ALL') params.country = country
    if (genre !== 'ALL') params.genre = genre
    const { items, total } = await getMovieList(params)
    setMovieList(items)
    setTotal(total)
  }

  return (
    <Wrapper>
      <PageTitle>🎬 MOVIE 🎬</PageTitle>
      <Form onSubmit={handleSubmit}>
        <select onChange={(e) => setCountry(e.target.value)} value={country}>
          <option value="ALL">전체</option>
          {countryList.map(({ code, name }) => (
            <option value={code} key={code}>
              {name}
            </option>
          ))}
        </select>
        <select onChange={(e) => setGenre(e.target.value)} value={genre}>
          <option value="ALL">전체</option>
          {genreList.map(({ code, name }) => (
            <option value={code} key={code}>
              {name}
            </option>
          ))}
        </select>
        <InputText
          placeholder="search"
          onChange={(e) => setText(e.target.value)}
        />
        <BtnSubmit>검색</BtnSubmit>
      </Form>
      <MovieList data={movieList} />
      <Pagination
        nowPage={page}
        total={total}
        onPageChange={(page) => setPage(page)}
      />
    </Wrapper>
  )
}

const Wrapper = styled.div``
const PageTitle = styled.h2``
const Form = styled.form`
  display: flex;
  padding: 15px;
`
const InputText = styled.input`
  flex: 1;
  margin-right: 15px;
`
const BtnSubmit = styled.button``

export default Movie

🎣 Book.jsx

import { useEffect, useState } from 'react'
import styled from 'styled-components'
import { getBookList } from '../../apis'
import BookList from '../organisms/BookList'
import Pagination from '../organisms/Pagination'
import { useLocation, useNavigate } from 'react-router-dom'
import qs from 'qs'

const Book = () => {
  const navigate = useNavigate()
  const { search } = useLocation()

  const [text, setText] = useState('')
  const [query, setQuery] = useState('')
  const [bookList, setBookList] = useState([])
  const [page, setPage] = useState(1)
  const [total, setTotal] = useState(0)

  useEffect(() => {
    const reset = () => {
      setText('')
      setQuery('')
      setPage(1)
      setTotal(0)
      setBookList([])
    }
    const { query, page } = qs.parse(search.slice(1))
    if (query) {
      setQuery(query)
      setText(query)
      if (page) setPage(+page)
    } else {
      reset()
    }
  }, [search])

  useEffect(() => {
    searchList()
  }, [page, query])
  const handleSubmit = (e) => {
    e.preventDefault()
    setPage(1)
    setQuery(text)
  }
  const searchList = async () => {
    if (query === '') return
    const start = page * 10 - 9
    const { items, total } = await getBookList({ query, start })
    setBookList(items)
    setTotal(total)

    const search = qs.stringify({ query, page })
    navigate({ search })
  }

  return (
    <Wrapper>
      <PageTitle>πŸ“š BOOK πŸ“š</PageTitle>
      <Form onSubmit={handleSubmit}>
        <InputText
          placeholder="search"
          value={text}
          onChange={(e) => setText(e.target.value)}
        />
        <BtnSubmit>검색</BtnSubmit>
      </Form>
      <BookList data={bookList} />
      <Pagination
        nowPage={page}
        total={total}
        onPageChange={(page) => setPage(page)}
      />
    </Wrapper>
  )
}

const Wrapper = styled.div``
const PageTitle = styled.h2``
const Form = styled.form`
  display: flex;
  padding: 15px;
`
const InputText = styled.input`
  flex: 1;
  margin-right: 15px;
`
const BtnSubmit = styled.button``

export default Book
728x90

'πŸ’™ React' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[REACT] useEffectκ°€ 2λ²ˆμ‹€ν–‰λ λ•Œ  (0) 2022.10.06
[REACT] To-do List λ§Œλ“€κΈ°  (0) 2022.10.06
[REACT] Instagram _ Log-In  (0) 2022.10.06
[REACT] Naver μ±… 검색  (0) 2022.10.06
[REACT] Naver μ˜ν™” 검색  (0) 2022.10.06