SMALL
안녕하세요~ 보라해바라기입니다!
오늘은 naver 영화 검색 api를 사용하여 라우터에 따른 영화검색 페이지를 만들어보았습니다:)
1. App.js
import './App.css';
import { Component } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './components/Home.js'
import Search from './components/Search.js'
import InputComp from './components/InputComp.js'
class App extends Component {
constructor(props){
super(props)
this.state={
}
}
render(){
return (
<div id='app'>
<BrowserRouter>
<InputComp/>
<Routes>
<Route exact path='/' element={<Home/>}/>
<Route exact path='/search' element={<Search/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
}
export default App;
2. App.css
#app{
width: 1100px;
height: 1400px;
margin: 0 auto;
background-color: aliceblue;
}
3.Home.js
import { Component } from 'react';
import '../css/Home.css'
class Home extends Component {
constructor(props){
super(props)
this.state={
}
}
render(){
return(
<div id='home'>
home
</div>
)
}
}
export default Home;
4.Home.css
#home{
width: 1000px;
height: 1000px;
background-color: thistle;
}
5.Search.js
import { Component } from 'react';
import '../css/Search.css'
import axios from 'axios'
import queryString from 'query-string'
import MovieList from './MovieList.js'
import Pagination from './Pagination.js';
//search한 값을 pagination
class Search extends Component {
constructor(props){
super(props)
this.state={
movieList:[],
currentPage:1,
moviePerPage:3
}
}
componentDidMount(){
// console.log('Search')
// console.log('window.location', window.location) // host, hostname, href, pathname. port...
// console.log('window.location.href', window.location.href)
// http://localhost:3000/search?searchText=블라블라블라&display=10&country=JPN
// console.log('window.location.search', window.location.search)
// ?searchText=블라블라블라&display=10&country=JPN
const queryObj=queryString.parse(window.location.search)
// console.log(queryObj) // {country: 'JPN', display: '10', searchText: '스파이더맨'}
// console.log(queryObj.searchText) //스파이더맨
const searchText = queryObj.searchText
this.searchMovie(searchText)
}
searchMovie=async(searchText)=>{
const {movieList} = this.state
console.log(searchText)
const axios_movies = await axios({
method:'get',
url:`/v1/search/movie.json?query=${searchText}`,
dataType:'json',
headers:{
"X-Naver-Client-Id": "OCTOqeR_MCymgnyep8zR",
"X-Naver-Client-Secret": "_UO4OJzKop"
}
})
this.setState({
movieList:axios_movies.data.items
})
console.log(axios_movies.data.items)
console.log(movieList)
}
setCurrentPage=(page)=>{
alert("페이지 설정(App.js):"+page)
this.setState({
currentPage:page
})
}
currentMovieList=(movieList)=>{
const {currentPage, moviePerPage} = this.state
const indexFirst = (currentPage-1)*moviePerPage
const indexLast = indexFirst+moviePerPage
const slicedMovieList = movieList.slice(indexFirst, indexLast)
return slicedMovieList;
}
render(){
const {movieList, moviePerPage, currentPage} = this.state
return(
<div id='search'>
<MovieList movieList={this.currentMovieList(movieList)}/>
<Pagination movieListLength={movieList.length} currentPage={currentPage}
moviePerPage={moviePerPage} setCurrentPage={this.setCurrentPage}/>
</div>
)
}
}
export default Search;
6.Search.css
#search{
width: 1000px;
height: auto;
background-color: lightgreen;
}
7.InputComp.js
import { Component } from 'react';
import '../css/InputComp.css'
class InputComp extends Component {
constructor(props){
super(props)
this.state={
searchText:''
}
}
searchBook=()=>{
alert("책 검색")
window.location.href=`/search?searchText=${this.state.searchText}&display=10&country=JPN`
}
inputChange=(e)=>{
this.setState({
searchText:e.target.value
})
}
render(){
return(
<div id='input-comp'>
<input type='text' placeholder='검색어' onChange={this.inputChange}/>
<button onClick={this.searchBook}>검색</button>
</div>
)
}
}
export default InputComp;
8.InputComp.css
#input-comp{
width: 1000px;
height: 50px;
margin-bottom: 10px;
background-color: lightpink;
}
9.Movie.js
import { Component } from 'react';
import '../css/Movie.css';
class Movie extends Component {
constructor(props){
super(props)
this.state={
}
}
render(){
return (
<div id="movie">
<div id='left-side'>
{this.props.image}
</div>
<div id='right-side'>
<span>제목: {this.props.title} </span>
<span>년도: {this.props.pubDate} </span>
<span>감독: {this.props.director}</span>
<span>배우: {this.props.actor}</span>
<span>평점: {this.props.userRating}/10</span>
</div>
</div>
);
}
}
export default Movie;
10.Movie.css
#movie{
width: 900px;
height: 300px;
background-color: yellowgreen;
margin: 10px;
}
#movie>#left-side{
float: left;
width: 250px;
height: 290px;
background-color: lightpink;
padding-top: 30px;
padding-left: 40px;
box-sizing: border-box;
}
#movie>#right-side{
float: left;
width: 550px;
height: 290px;
background-color: lightblue;
}
#movie>#right-side>span{
display: block;
width: 540px;
height: 35px;
padding-top: 10px;
box-sizing: border-box;
}
#movie>#right-side>span:first-child{
background-color: lightgray;
}
#movie>#right-side>span:nth-child(2){
background-color: lightgoldenrodyellow;
}
#movie>#right-side>span:nth-child(3){
background-color: lightcyan;
}
#movie>#right-side>span:nth-child(4){
background-color: sandybrown;
height: auto;
}
#movie>#right-side>span:nth-child(5){
background-color: plum;
}
11.MovieList.js
import { Component } from 'react';
import '../css/MovieList.css';
import Movie from './Movie';
class MovieList extends Component {
constructor(props){
super(props)
this.state={
}
}
// 제목에 나오는 html태그 제거해야 함 -> (구글링: react 태그 제거 ~ replace)
render(){
const result= this.props.movieList.map(
(data) => (<Movie key={data.id}
image = {<img src= {data.image}/>}
title={data.title.replace(/(<([^>]+)>)/ig,"")}
pubDate={data.pubDate} director={data.director.replace(/(<([^>]+)>)/ig,"").replace(/\|/ig,",")}
actor={data.actor.replace(/(<([^>]+)>)/ig,"").replace(/\|/ig,",")} userRating={data.userRating}/>)
)
// data.title.replace(/(<([^>]+)>)/ig,"") => 모든 태그를 제거
// data.director.replace(/\|/ig,",") => |를 한꺼번에 바꾸기 (| 앞에 무효화할 수 있도록 \키 넣기)
return (
<div id="movie-list">
{result}
</div>
);
}
}
export default MovieList;
12.MovieList.css
#movie-list{
width: 900px;
height: auto;
margin: 0 auto;
}
img{
width: 180px;
height: 230px;
}
13.Pagination.js
import { Component } from 'react';
import '../css/Pagination.css';
class Pagination extends Component {
constructor(props){
super(props)
this.state={
}
}
setCurrentPage=(page)=>{
alert(page+"페이지 클릭(Pagination.js)")
this.props.setCurrentPage(page)
}
prevPage=()=>{
alert("이전")
const {currentPage, setCurrentPage} = this.props
if (currentPage==1){
alert("여기는 첫 페이지 입니다.")
return
}
setCurrentPage(currentPage-1)
}
nextPage=()=>{
alert("다음")
const {currentPage, setCurrentPage} = this.props
const {lastPageNum} = this.state
if (currentPage+1 > lastPageNum){
alert("여기는 마지막 페이지 입니다.")
return
}
setCurrentPage(currentPage+1)
}
render(){
const {movieListLength, moviePerPage} = this.props
let pageNumbers=[];
const lastPageNum = Math.ceil(movieListLength/moviePerPage)
for(var i=1; i<=lastPageNum; i++){
pageNumbers.push(i)
}
const result=pageNumbers.map(
(data)=>(<span className='page' key={data}
onClick={()=>this.setCurrentPage(data)}>{data}</span>)
)
return (
<div id="pagination">
<div>
총 글 갯수: {movieListLength}
</div>
<div>
페이지당 글 갯수: {moviePerPage}
</div>
<div>
<span className='page' onClick={this.prevPage}>
<
</span>
<span>{result}</span>
<span className='page' onClick={this.nextPage}>
>
</span>
</div>
</div>
);
}
}
export default Pagination;
14.Pagination.css
#pagination{
width: 900px;
height: 100px;
background-color: springgreen;
position: relative;
margin-left: 60px;
}
.page{
display:inline-block;
width:35px;
height:35px;
border:1px solid black;
margin:5px;
text-align: center;
padding-top:5px;
box-sizing: border-box;
background-color: darkgray;
cursor: pointer;
}
#pagination>div:nth-child(3){
position: absolute;
left: 240px;
}
15. 실행결과

728x90
'React' 카테고리의 다른 글
[Project] 페이지 이동 시, 화면을 맨 위로 자동 스크롤 (0) | 2023.07.12 |
---|---|
[Project] 리액트 프로젝트 기획 (0) | 2023.06.19 |
[React 공식 문서] Tania Rascia React Tutorial Note (0) | 2023.05.08 |
[FrontEnd6] yts-movie-api를 사용하여 영화 리스트 만들기 (yts-api, axios, pagination) (0) | 2022.09.16 |
[React] component 요소를 이용한 게시판 구조 짜기 (페이지 넘기기, 원하는 포스팅 갯수 만큼 보이도록 하기 etc..) (0) | 2022.08.24 |
댓글