react

리액트 _12_라우터(Router)페이징

새내기개발자 2020. 5. 16. 16:54

1. 전에 만든 movie-server를 복사해서 가져온다. 

   안에 app.get 부분의 링크를 /movie_real2로 바꾸고 페이지를 바꿀 수 있도록 page변수를 생성한다.

app.get("/movie_real2",(request,response)=>{
    //url : mongodb 주소
    var page=request.query.page;
    var rowSize=12;
    var skip=(page*rowSize)-rowSize;

    var url="mongodb://211.238.142.181:27017"
    Client.connect(url,(err,client)=>{
            var db = client.db("mydb");
            db.collection("movie").find({cateno:1}).skip(skip).limit(rowSize).toArray(function (err,docs) {
                response.json(docs)
                client.close();
            })
    })
})

* 몽고DB에서 페이지 나누는 방법 (skip, limit)

  1 page => skip이 0 (0~11번까지)

  2 page -> skip이 12 (12~23번까지)

 

2. 총페이지를 찾는 /movie_total가 링크인 것도 만든다.

 * ceil = 소수점있으면 올림

 * string으로 넘어오기 때문에 cateno앞에 number라고 해주어야한다. 

app.get("/movie_total",(request,response)=>{
    var cateno=request.query.cateno;
    var url="mongodb://211.238.142.181:27017"
    Client.connect(url,(err,client)=>{
        var db = client.db("mydb");
        // =SELECT COUNT(*) FROM movie WHRER cateno=1
        db.collection("movie").find({cateno: Number(cateno)}).count(function (err,count) {
            response.json({total:Math.ceil(count/12.0)})
            client.close()
            return count;
        })
    })
})

3. MovieReal 에서 값을 가져오고 페이징 적용을 해보자

변수를 3개 잡아준다.

  constructor(props) {
        super(props);
        this.state={
            movie:[],
            page:1,
            totalpage:0
        }

    }

서버에서 request.를 2개 요청했으니 params도 두개 해야한다. 

this.setState({totalpage:result.data.total}) 이거는 서버에서 response로 값을 넘겨준 것을 넣으면 된다. 

componentDidMount() {
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
        axios.get("http://localhost:3355/movie_total",{
            params:{
                cateno: 1
            }
        }).then((result)=>{
            this.setState({totalpage:result.data.total})
        })
    }

4. render 안에 이전, 다음 버튼을 넣는다.

  render() {
        return (
            <React.Fragment>
                <div className={"row"}>

                </div>
                <div className={"row text-center"}>
                    <button className={"btn btn-lg btn-primary"}>이전</button>
                    {this.state.page}page / {this.state.totalpage} pages
                    <button className={"btn btn-lg btn-primary"}>다음</button>
                </div>
            </React.Fragment>
        );
    }
}

5. 서버를 다시 실행하고(node movie-server) 새 터미널 열어서 npm start해준다.

현재상영영화를 클릭하면 이렇게 버튼 만든 모양이 나온다.

 

6. 이제 페이징 위에 이미지를 넣어보자

   render() {
        const html=this.state.movie.map((m)=>
            <div className="col-md-4">
                <div className="thumbnail">
                    <a href="/w3images/lights.jpg">
                        <img src={m.poster} alt="Lights" style={{"width":"100%"}}/>
                        <div className="caption">
                            <p>{m.title}</p>
                        </div>
                    </a>
                </div>
            </div>
        )
        return (
            <React.Fragment>
                <div className={"row"}>
                    {html}
                </div>
                <div className={"row text-center"}>
                    <button className={"btn btn-lg btn-primary"}>이전</button>
                    {this.state.page}page / {this.state.totalpage} pages
                    <button className={"btn btn-lg btn-primary"}>다음</button>
                </div>
            </React.Fragment>
        );
    }
}

7. 버튼 이벤트 처리만 하면 된다. 

   constructor에 이벤트(onPrev)를 등록한다. 

    constructor(props) {
        super(props);
        this.state={
            movie:[],
            page:1,
            totalpage:0
        }
        this.onPrev=this.onPrev.bind(this);
        this.onNext=this.onNext.bind(this);

    }
    onPrev(){
        
    }
    onNext(){
        
    }

8. onPrev 와 onNext를 삼항연산식으로 채운다.

    onPrev(){
        this.state.page=this.state.page>1?this.state.page-1:this.state.page;
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
    }
    onNext(){
        this.state.page=this.state.page<this.state.totalpage?this.state.page+1:this.state.page;
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
    }

9. 버튼에 onclick 이벤트를 준다.

  <div className={"row text-center"}>
       <button className={"btn btn-lg btn-primary"} onClick={this.onPrev}>이전</button>
        {this.state.page}page / {this.state.totalpage} pages
        <button className={"btn btn-lg btn-primary"} onClick={this.onNext}>다음</button>
  </div>

페이징이 되는 것을 확인 할 수 있다. 

 

+) movie-server 전체코드

const express=require("express")
//express는 간단한 서버를 제작할 때 사용
const request=require("request")
//request는 다른 사이트 서버를 연결해서 데이터 읽는 역할을 한다.
const app=express();
//서버 생성
const port=3355;
//서버 포트번호는 0~65535 중에 하나를 선택해야 한다. (0~1023은 이미 사용중)
//포트 충돌 방지 코드
app.all('/*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
});
//서버 대기중: .listen()
app.listen(port,()=>{
    console.log("Server Start...","http://localhost:3355")
})
//경로명 가져오기: .get
app.get("/",(request,response)=>{
    response.send("Hello Node Server!!")
})
// mongodb 연결
const Client=require("mongodb").MongoClient
/*
    몽고디비 =>NoSQL
    find() => select * from movie 의미
    find({mno:1}) => select * from movie where mno=1 의미
 */
// Client/movie라고 하면 아래 코드를 실행한다.
app.get("/movie_real2",(request,response)=>{
    //url : mongodb 주소
    var page=request.query.page;
    var rowSize=12;
    var skip=(page*rowSize)-rowSize;

    var url="mongodb://211.238.142.181:27017"
    Client.connect(url,(err,client)=>{
            var db = client.db("mydb");
            db.collection("movie").find({cateno:1}).skip(skip).limit(rowSize).toArray(function (err,docs) {
                response.json(docs)
                client.close();
            })
    })
})

app.get("/movie_total",(request,response)=>{
    var cateno=request.query.cateno;
    var url="mongodb://211.238.142.181:27017"
    Client.connect(url,(err,client)=>{
        var db = client.db("mydb");
        // =SELECT COUNT(*) FROM movie WHRER cateno=1
        db.collection("movie").find({cateno: Number(cateno)}).count(function (err,count) {
            response.json({total:Math.ceil(count/12.0)})
            client.close()
            return count;
        })
    })
})

app.get("/movie_home",(req,res)=>{
     var no=req.query.no; // /movie_home?no=1 라고 사용자가 쳤을 때 no
     var site="";
     if(no==1){
        site="searchMainDailyBoxOffice.do"//일일 박스오피스
     }
     else if(no==2){
         site="searchMainRealTicket.do"//실시간 예매율
     }
     else if(no==3){
         site="searchMainDailySeatTicket.do"//좌석점유율순위
     }
     else if(no==4){
         site="searchMainOnlineDailyBoxOffice.do"//온라인상영관 일일
     }
     var url="http://www.kobis.or.kr/kobis/business/main/"+site;

     request({url:url},function (err,request,json) {
        console.log(json);
        res.json(JSON.parse(json));
     })
})


+) movieReal 전체코드

import React, {Component} from 'react';
import axios from 'axios'
class MovieReal extends Component{
    constructor(props) {
        super(props);
        this.state={
            movie:[],
            page:1,
            totalpage:0
        }
        this.onPrev=this.onPrev.bind(this);
        this.onNext=this.onNext.bind(this);

    }
    onPrev(){
        this.state.page=this.state.page>1?this.state.page-1:this.state.page;
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
    }
    onNext(){
        this.state.page=this.state.page<this.state.totalpage?this.state.page+1:this.state.page;
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
    }
    componentDidMount() {
        axios.get("http://localhost:3355/movie_real2",{
            params:{
                page: this.state.page
            }
        }).then((result)=>{
            this.setState({movie:result.data});
        })
        axios.get("http://localhost:3355/movie_total",{
            params:{
                cateno: 1
            }
        }).then((result)=>{
            this.setState({totalpage:result.data.total})
        })
    }
    render() {
        const html=this.state.movie.map((m)=>
            <div className="col-md-4">
                <div className="thumbnail">
                    <a href="/w3images/lights.jpg">
                        <img src={m.poster} alt="Lights" style={{"width":"100%"}}/>
                        <div className="caption">
                            <p>{m.title}</p>
                        </div>
                    </a>
                </div>
            </div>
        )
        return (
            <React.Fragment>
                <div className={"row"}>
                    {html}
                </div>
                <div className={"row text-center"}>
                    <button className={"btn btn-lg btn-primary"} onClick={this.onPrev}>이전</button>
                    {this.state.page}page / {this.state.totalpage} pages
                    <button className={"btn btn-lg btn-primary"} onClick={this.onNext}>다음</button>
                </div>
            </React.Fragment>
        );
    }
}
export default MovieReal;
반응형