리액트 _12_라우터(Router)페이징
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;