import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Main from './components/pages/Main'
import Movie from './components/pages/Movie'
import Book from './components/pages/Book'
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Main />} />
<Route path="/movie" element={<Movie />} />
<Route path="/book" element={<Book />} />
</Routes>
</BrowserRouter>
)
}
export default Router
import { Link } from 'react-router-dom'
import styled from 'styled-components'
const Main = () => {
return (
<Wrapper>
<PageTitle>영화 🎬 & 책 📚 검색</PageTitle>
<Link to="/Movie">
<Button>영화 🎬</Button>
</Link>
<Link to="/Book">
<Button>책 📚</Button>
</Link>
</Wrapper>
)
}
const Wrapper = styled.div`
padding: 15px;
`
const PageTitle = styled.h2`
text-align: center;
`
const Button = styled.button`
width: 100%;
margin: 10px 0;
height: 100px;
font-size: 24px;
border: none;
border-radius: 4px;
`
export default Main
import { useState } from 'react'
import styled from 'styled-components'
import { getMovieList } from '../../apis'
import MovieList from '../organisms/MovieList'
const Movie = () => {
const [text, setText] = useState('')
const [movieList, setMovieList] = useState([])
const handleSubmit = async (e) => {
e.preventDefault()
const { items } = await getMovieList({ query: text })
setMovieList(items)
}
return (
<Wrapper>
<PageTitle>🎬 Movie 🎬</PageTitle>
<Form onSubmit={handleSubmit}>
<InputText
placeholder="search"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<BtnSubmit>검색</BtnSubmit>
</Form>
<MovieList data={movieList} />
</Wrapper>
)
}
const Wrapper = styled.div``
const PageTitle = styled.h2``
const Form = styled.form`
display: flex;
padding: 15px;
`
const InputText = styled.input`
flex: 1;
margin-right: 15px;
`
const BtnSubmit = styled.button``
export default Movie
import styled from 'styled-components'
const MovieList = ({ data }) => {
return (
<List>
{data.map(({ image, title }) => (
<Item key={image}>
<Thumbnail src={image} />
<Title dangerouslySetInnerHTML={{ __html: title }} />
</Item>
))}
</List>
)
}
const List = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
padding: 15px;
`
const Item = styled.div``
const Thumbnail = styled.img`
width: 100%;
`
const Title = styled.span``
export default MovieList
import axios from 'axios'
export const getMovieList = async (params) => {
const { data } = await axios.get('/v1/search/movie.json', {
headers: {
'X-Naver-Client-Id': 'ID',
'X-Naver-Client-Secret': 'PW',
},
params,
})
return data
}
📌 서버를 만들수 없으니 package.json 에서
"proxy": "https://openapi.naver.com" 추가해주기
- proxy 는 개발과정에서만 사용가능. 배포 할때는 서버 필요함.
(즉, 연습때만 사용할수 있음) 📌
export const countryList = [
{
code: 'KR',
name: '한국',
},
{
code: 'JP',
name: '일본',
},
{
code: 'US',
name: '미국',
},
{
code: 'HK',
name: '홍콩',
},
{
code: 'GB',
name: '영국',
},
{
code: 'FR',
name: '프랑스',
},
{
code: 'ETC',
name: '기타',
},
]
export const genreList = [
{
code: '1',
name: '드라마',
},
{
code: '2',
name: '판타지',
},
{
code: '3',
name: '공포',
},
{
code: '4',
name: '로맨스',
},
{
code: '5',
name: '미스터리',
},
{
code: '6',
name: '느와르',
},
{
code: '7',
name: '애니메이션',
},
]
import { useEffect, useState } from 'react'
import styled from 'styled-components'
import { getMovieList } from '../../apis'
import MovieList from '../organisms/MovieList'
📍import { countryList, genreList } from '../../datas'
const Movie = () => {
const [text, setText] = useState('')
📍const [country, setCountry] = useState('ALL')
📍const [genre, setGenre] = useState('ALL')
const [movieList, setMovieList] = useState([])
📍useEffect(() => {
searchMovieList()
}, [country, genre])
const handleSubmit = async (e) => {
e.preventDefault()
searchMovieList()
}
📍const searchMovieList = async () => {
if (text === '') return
// const params = { query: text, country }
// if(country === "ALL") delete params.country;
const params = { query: text }
if (country !== 'ALL') params.country = country
if (genre !== 'ALL') params.genre = genre
const { items } = await getMovieList(params)
setMovieList(items)
}
return (
<Wrapper>
<PageTitle>🎬 Movie 🎬</PageTitle>
<Form onSubmit={handleSubmit}>
📍 <select onChange={(e) => setCountry(e.target.value)} value={country}>
<option value="ALL">전체</option>
{countryList.map(({ code, name }) => (
<option value={code} key={code}>
{name}
</option>
))}
</select>
📍 <select onChange={(e) => setGenre(e.target.value)} value={genre}>
<option value="ALL">전체</option>
{genreList.map(({ code, name }) => (
<option value={code} key={code}>
{name}
</option>
))}
</select>
<InputText
placeholder="search"
onChange={(e) => setText(e.target.value)}
/>
<BtnSubmit>검색</BtnSubmit>
</Form>
<MovieList data={movieList} />
</Wrapper>
)
}
export default Movie