[React] component 요소를 이용한 게시판 구조 짜기 (페이지 넘기기, 원하는 포스팅 갯수 만큼 보이도록 하기 etc..)

    SMALL

    안녕하세요~ 보라해바라기입니다!

     

    요즘 저는 react를 배우고 있답니다 ㅎㅎ

     

    react의 component요소가 개발을 할 때 편리하게 작용하더군요!

     

    이 특성을 살려 간단하게 게시판 구조를 만들어보았습니다.

     

    1. App.js

    import { Component } from 'react';
    import './App.css';
    import SmList from './components/SmList.js'
    import Pagination from './components/Pagination.js'
    
    class App extends Component {
      constructor(props){
        super(props)
        this.state={
          smList:[
            {imgSrc: 'tvxq.jpg', no:1, name:'동방신기', debut_year:2003, member:2},
            {imgSrc: 'girls_generation.jpg', no:2, name:'소녀시대', debut_year:2007, member:9},
            {imgSrc: 'superJunior.jpg', no:3, name:'슈퍼주니어', debut_year:2005, member:10},
            {imgSrc: 'shinee.jpg', no:4, name:'샤이니', debut_year:2008, member:5},
            {imgSrc: 'fx.jpg', no:5, name:'에프엑스', debut_year:2009, member:5},
            {imgSrc: 'wayv.jpg', no:6, name:'Way-v', debut_year:2019, member:7},
            {imgSrc: 'aespa.jpg', no:7, name:'에스파', debut_year:2020, member:4},
            {imgSrc: 'exo.jpg', no:8, name:'엑소', debut_year:2012, member:9},
            {imgSrc: 'redvelvet.jpg', no:9, name:'레드벨벳', debut_year:2014, member:5},
            {imgSrc: 'nct127.jpg', no:10, name:'NCT 127', debut_year:2016, member:10},
            {imgSrc: 'nctdream.jpg', no:11, name:'NCT DREAM', debut_year:2016, member:7}
          ],
          smListPerPage: 3,
          currentPage: 1
        }
      }
    
      setCurrentPage=(page)=>{
        alert(page+"페이지 입력!(App.js)")
        this.setState({
          currentPage:page
        })
      }
    
      currentSmList=(smList)=>{
        const {currentPage, smListPerPage} = this.state
        const indexOfFirst = (currentPage-1) * smListPerPage
        const indexOfLast = indexOfFirst + smListPerPage
        const sliceSmList = this.state.smList.slice(indexOfFirst, indexOfLast)
        return sliceSmList;
      }
    
      render(){
        const {smList, currentPage, smListPerPage} = this.state
        return (
          <div id="app">
            <SmList smList={this.currentSmList(smList)}></SmList>
            <Pagination smListLength={smList.length}
            currentPage={currentPage} smListPerPage={smListPerPage}
            setCurrentPage={this.setCurrentPage}></Pagination>
          </div>
        );
      }
    }
    
    export default App;

     

    2. App.css

    #app {
      width: 900px;
      height: 900px;
      background-color: rgb(248, 229, 232);
    }

     

    3. Sm.js (하나의 포스트)

    import { Component } from 'react';
    import '../css/Sm.css';
    
    
    class Sm extends Component {
      constructor(props){
        super(props)
        this.state={
          
        }
      }
    
      render(){
        return (
          <div id="sm">
            <span><img src= {this.props.imgSrc}/></span>
            <span>번호: {this.props.no} </span>
            <span>팀 이름: {this.props.name} </span>
            <span>데뷔년도: {this.props.debut_year} </span>
            <span>멤버 수: {this.props.member} </span>
          </div>
        );
      }
    }
    
    export default Sm;

     

    4. Sm.css

    #sm{
        width: 90%;
        height: 100px;
        background-color: plum;
        margin: 10px;
    }
    
    #sm>span{
        float: left;
        height: 100%;
        text-align: center;
        padding-top: 10px;
        box-sizing: border-box;
    }
    
    #sm>span:first-child{
        width: 20%;
        background-color: aliceblue;
    }
    
    #sm>span:first-child>img{
        width: 120px;
        height: 80px;
        background-color: aliceblue;
    }
    
    #sm>span:nth-child(2){
        width: 10%;
        background-color: rgb(205, 229, 250);
    }
    
    #sm>span:nth-child(3){
        width: 25%;
        background-color: rgb(170, 215, 254);
    }
    
    #sm>span:nth-child(4){
        width: 20%;
        background-color: rgb(163, 209, 250);
    }
    
    #sm>span:nth-child(5){
        width: 20%;
        background-color: rgb(121, 188, 246);
    }

     

    5. SmList.js (포스트들을 모은 전체 화면)

    import { Component } from 'react';
    import '../css/SmList.css';
    import Sm from './Sm.js'
    
    
    class SmList extends Component {
      constructor(props){
        super(props)
        this.state={
          
        }
      }
    
      render(){
    
        const result = this.props.smList.map(
            (data) => (<Sm key={data.img} imgSrc={data.imgSrc} no={data.no}
            name={data.name} debut_year={data.debut_year} member={data.member}/>)
        )
    
        return (
          <div id="sm-list">
            {result}
          </div>
        );
      }
    }
    
    export default SmList;

     

    6. SmList.css

    #sm-list{
        width: 90%;
        height: auto;
        background-color: violet;
    }

     

    7. Pagination.js (페이지 번호 있는 부분)

    import { Component } from 'react';
    import '../css/Pagination.css';
    
    
    class Pagination extends Component {
      constructor(props){
        super(props)
        this.state={
          
        }
      }
    
      componentDidMount=()=>{
        var pageList = document.getElementsByClassName('page')
        pageList[1].style.color="hotpink"
        pageList[1].style.backgroundColor="ivory"
      }
    
      setCurrentPage=(page)=>{
        alert(page+"페이지 입력!(Pagination.js)")
        this.props.setCurrentPage(page)
        this.setAllDefault()
        this.setPageHighLight(page)
      }
    
      prevFunc=()=>{
        alert("이전")
        const {currentPage, setCurrentPage} = this.props
        if (currentPage === 1){
          alert("첫페이지 입니다.")
          return
        }
        setCurrentPage(currentPage-1)
        this.setCurrentPage(currentPage-1)
      }
    
      nextFunc=()=>{
        alert("다음")
        const {currentPage, setCurrentPage, smListLength, smListPerPage} = this.props
        const endPage = Math.ceil(smListLength/smListPerPage)
        if (currentPage+1 > endPage){
          alert("끝페이지 입니다.")
          return
        }
        setCurrentPage(currentPage+1)
        this.setCurrentPage(currentPage+1)
      }
    
      setAllDefault=()=>{
        alert("모두 해제!")
        var pageList = document.getElementsByClassName('page')
        const pageListLength = pageList.length
        for(var i=0; i<pageListLength; i++){
          pageList[i].style.color="ivory"
          pageList[i].style.backgroundColor="hotpink"
        } 
      }
    
      setPageHighLight=(page)=>{
        alert(page+"페이지 클릭!")
        var pageList=document.getElementsByClassName('page')
        pageList[page].style.color="hotpink"
        pageList[page].style.backgroundColor="ivory"
      }
    
      render(){
    
        const {smListLength, smListPerPage} = this.props
        let pageNumbers = [];
        const lastPageNum = Math.ceil(smListLength/smListPerPage)
        for(var i=1; i<=lastPageNum; i++) {
            pageNumbers.push(i)
        }
    
        const pageList = pageNumbers.map(
            (data) => (<span className='page' 
            onClick={()=>this.setCurrentPage(data)}>{data}</span>)
        )
    
        return (
          <div id="pagination">
            <div>총 글 갯수: {smListLength}</div>
            <div>페이지당 글 갯수: {smListPerPage}</div>
            <div>
                <span className='page' onClick={this.prevFunc}>&lt;</span>
                {pageList}
                <span className='page' onClick={this.nextFunc}>&gt;</span>
            </div>
          </div>
        );
      }
    }
    
    export default Pagination;

     

    8. Paginaton.css

    #pagination{
        width: 90%;
        height: 100px;
        background-color: lightcoral;
    }
    
    #pagination>div:first-child{
        background-color: rgb(236, 195, 195);
    }
    
    #pagination>div:nth-child(2){
        background-color: rgb(243, 174, 174);
    }
    
    .page{
        display: inline-block;
        width: 35px;
        height: 35px;
        background-color: hotpink;
        border: 1px solid ivory;
        color: ivory;
        text-align: center;
        margin: 5px;
        padding-top: 5px;
        box-sizing: border-box;
        cursor: pointer;
    }
    
    #pagination span:hover{
        font-weight: bold;
    }

     

    9. 결과

    (1) 페이지 번호 누르면 이동 & 현재 페이지 번호 버튼 색깔 바뀜

     

    (2) 이전, 다음 버튼

    728x90

    댓글