본문 바로가기
React

[React] 페이지네이션2 / 이전다음버튼, 현재페이지 버튼 하이라이트

by Yeoseungwon 2023. 6. 11.
728x90

저번시간 요약 

 

1.npx

2.App.js 클래스형 컴포넌트로 변경

3.PostList.js , Pagination.js

4.App에 state추가 - 길이가 10인 JSON배열 (게시글)

    (게시글 - 글번호, 글제목, 글쓴이, 글쓴날짜, 파일첨부여부, 조회수)

5.App의 상태값 postlist를 PostList에 주입시킨다 (넘긴다)

     App- <PostList postlist = {this.state.postlist}/>

               <Pagination/>

6. Post컴포넌트를 만들고, PostList에서 import하고 map메서드로 반복생성

      (PostList 컴포넌트가 App한테 넘겨받은 postlist 배열데이터를 이용해서 map메서드로

        Post컴포넌트에 주입시켜서 Post 컴포넌트 반복생성)

 

PostList컴포넌트 내부 

        const result = this.props.postlist.map(

               (data) => (<Post key={data.no} no={data.no} title={data.title} />)

7.게시글 목록이 나오는지 확인 

     App - PostList

                     -Post 

                     -Post

                     -Post

                     -....~10개

              -Pagination

   그다음에는 페이지당 3개씩 찍는걸 고려해본다 

8. slice? Pagination?

   Pagination 에 페이지번호 생성하기 (Pagination에 게시글 총 갯수, 페이지당 게시글 갯수를 넘긴다)

   < Pagination total={this.state.postlist.length} postPerPage={this.state.postPerPage}/>   //  10,3 을 넘김

  

페이지당 게시글개수 계산해서 페이지번호 생성하기. 

페이지당 갯수를 계산할 때 언어마다 다른 결과가 나오므로 나누기 결과 콘솔찍어보기 

10/3 -> 3.33333 -> Math.ceil() -> 4 (JavaScript, Python)

10/3 -> 3 -> 3+1(10%1) ->  Java

 

Pagination 에서 

const endPage = Math.ceil(total / postPerPage)   

console.log(endPage) // 4

 

let pageNumbers=[];

for(var i=1; i<=endPage; i++){

   pageNumbers.push(i)

}

console.log(pageNumbers) // [1,2,3,4]

 

const result = pageNumbers.map(

        (page) => (<span id='page'>{page}</span>)

)

 

박스모양으로 찍을거기 때문에 map으로 span 찍어주기 

span에 id or className 줘서 박스모양 디자인 (경계선, 가운데정렬, 마진...)

 

 

 

9.page에 클릭이벤트 + 함수 연결 클릭한 페이지번호 확인

10. 클릭한 페이지번호 App로 넘겨서 현재페이지 번호 변경

      (App의 currentPage상태값을 변경)

11.

      <PostList postlist={postlist}/> 이렇게 하면 다 나옴 

   ==> <PostList postlist = {this.currentPostList(postlist)}/ >  이렇게 바꿔주기

12. currnetPostList 함수가 현재페이지번호, 페이지당 갯수, slice로 현재 페이지번호에 해당하는 게시글만 추출해서 반환 

 

 

 

 

--------------------------------------------------------------------------------------------------------

 

Pagination.js 이전,다음 버튼 만들어주고 클릭 이벤트 걸기 

** 선택된 페이지번호 active 클래스로 하이라이트 (조건부 클래스 이용)

 

&lt;  ( < )

&gt; ( > )

Pagination.js

        return(
            <div id='pagination'>
                <div id='pagenation-inner'>
                    <span id='page' onClick={this.prevPage}>&lt;</span>
                    {result}
                    <span id='page' onClick={this.nextPage}>&gt;</span>
                </div>
            </div>
        )
    }
Pagination.js

    prevPage=()=>{
        alert('이전 버튼 클릭 ')
    }
    nextPage=()=>{
        alert('다음 버튼 클릭 ')
    }

 

Pagination에서 현재페이지를 알아야하니 App.js 에서 현재페이지 주입시켜주기 

currentPage 알려주기 

App.js

    return(
       <div id='App'>
         <PostList 
        //1단계  postlist={postlist} 그다음 페이지번호에 맞는 페이지당 게시글 목록 
        postlist={this.currentPostList(postlist)}/>
        <Pagination total={postlist.length}
                     postPerPage={postPerPage}
                     currentPage={currentPage}
                     setCurrentPage={this.setCurrentPage}//페이지네이션에 현재페이지 상태 넘김
                     />
       </div>
    )
  }

Pagination에서 App에서 알려준 현재페이지 콘솔 찍어보고 이전버튼 클릭했을때 페이지 변할수 있도록 if 문 써주기 

Pagination.js

    prevPage=()=>{
        alert('이전 버튼 클릭 ')
        //현재페이지가 뭔지 알아야함 
        console.log('현재페이지 : ' + this.props.currentPage)
        const {currentPage} = this.props

        if(currentPage-1 <1 ){
            alert('이동불가!')
            return //1일때는 못가게 리턴으로 끝내버리기 
        }
        this.props.setCurrentPage(currentPage-1)
    }

* 이전버튼 클릭이벤트 완성 

다음버튼도 만들어주기 

Pagination.js

    nextPage=()=>{
        alert('다음 버튼 클릭 ')

        const {currentPage, total, postPerPage} = this.props
        const endPage = Math.ceil(total/postPerPage) // 4 
        if(currentPage+1 > endPage){
            alert('이동불가')
            return
        }
        this.props.setCurrentPage(currentPage+1)
        }

이전에 사용한 endPage 구했던 계산 그대로 이용하기 

* 다음버튼 완성 

 

 

이제 현재페이지 나타낼수있는 페이지버튼 하이라이트 만들어주기 

css로 active 클래스로 하이라이트 만들어서 적용해보면 기존 id의 css 에 우선순위가 밀려서 안먹힘 

>> 클래스css  !important 해주기 

Pagination.js

        const result = pageNumbers.map(
            (page)  => (<span id='page'className='active' onClick={()=>this.pageClick(page)}>{page}</span>) 
        )
#page:hover{
    background-color: #777;
}

.active{
    background-color: #777 !important;
    /* css 우선순위가 밀려버려서 important 줘야함 */
    color: #ffffff;
}

 

이제 Pagination.js 의 render에서 조건부 렌더링 해주기 

               className={ this.props.currentPage===page ? 'active' : '' 

현재페이지와 같은 페이지번호에 active 클래스추가

const result = pageNumbers.map(
   (page)  => (<span id='page'
               className={ this.props.currentPage===page ? 'active' : '' } 
               onClick={()=>this.pageClick(page)}>{page}</span>) 
)

 

 

 

Pagination.js에 자꾸 경고가뜸 >> 이유는 key 설정을 안해줬기 때문이다. 

Pagination.js 완성

import '../css/Pagination.css';
import { Component } from 'react';

class Pagination extends Component{
    constructor(props){
        super(props)
        this.state={

        }
    }

    pageClick=(page)=>{
        // alert('페이지클릭 ' +page) //이벤트 걸리는지 확인
        //매개변수 page 받아서 몇페이지를 눌렀는지 확인되어야함 -> 문제가있음 클릭을 안해도 그냥 모든 페이지번호가 호출되버림 1,2,3,4 
        //onClick함수에 ()=> 이것만 쓰면 강제호출 막아줌
        //이제 클릭된 번호를 App.js 에 넘겨줘야함 그다음 페이지에 맞는 배열데이터를 postlist한테 넘겨야함 
        this.props.setCurrentPage(page)//App가 넘긴 함수
    }

    prevPage=()=>{
        alert('이전 버튼 클릭 ')
        //현재페이지가 뭔지 알아야함 
        console.log('현재페이지 : ' + this.props.currentPage)
        const {currentPage} = this.props

        if(currentPage-1 <1 ){
            alert('이동불가!')
            return //1일때는 못가게 리턴으로 끝내버리기 
        }
        this.props.setCurrentPage(currentPage-1)
    }
    nextPage=()=>{
        alert('다음 버튼 클릭 ')

        const {currentPage, total, postPerPage} = this.props
        const endPage = Math.ceil(total/postPerPage) // 4 
        if(currentPage+1 > endPage){
            alert('이동불가')
            return
        }
        this.props.setCurrentPage(currentPage+1)
        }


    render(){

        const{total, postPerPage} = this.props
                //10,3
                //3,3,3,1 = 총 4페이지
                console.log('total : ' +total)
                console.log('postPerPage : ' +postPerPage)
        const endPage = Math.ceil(total/postPerPage)
        //자바스크립트에서는 3.3 그럼 올림(Math.ceil())시켜서 4를 만들어줘야함

        let pageNumbers=[] //게시글정보가 바뀌기 때문에 페이지번호 갱신작업을 해줘야함
        for(var i=1; i<=endPage; i++){
            pageNumbers.push(i)
        }
        console.log(pageNumbers) // [1,2,3,4] 페이지 번호 확인

        const result = pageNumbers.map(
            (page)  => (<span key = {page} id='page'
                        className={ this.props.currentPage===page ? 'active' : '' } 
                        onClick={()=>this.pageClick(page)}>{page}</span>) 
        )

        return(
            <div id='pagination'>
                <div id='pagenation-inner'>
                    {/* <button className='side-btn' onClick={this.boforePage}>이전</button> */}
                    <span id='page' onClick={this.prevPage}>&lt;</span>
                    {result}
                    {/* <button className='side-btn' onClick={this.afterPage}>다음</button> */}
                    <span id='page' onClick={this.nextPage}>&gt;</span>

                </div>
            </div>
        )
    }
}

export default Pagination;
728x90