React

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

보라해바라기 2022. 8. 24. 23:50
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