🀍 은지log 🀍

[REACT] Naver μ˜ν™” 검색 λ³Έλ¬Έ

πŸ’™ React

[REACT] Naver μ˜ν™” 검색

Eun_zii 2022. 10. 6. 13:47

🎣 1. Router.js 생성

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

🎣 2. Main.jsx

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

🎣 3. Movie.jsx

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

🎣 3-1. MovieList.jsx

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

🎣 3-2. src>apis>index.js νŒŒμΌμƒμ„±

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 λŠ” κ°œλ°œκ³Όμ •μ—μ„œλ§Œ μ‚¬μš©κ°€λŠ₯. 배포 ν• λ•ŒλŠ” μ„œλ²„ ν•„μš”ν•¨.
(즉, μ—°μŠ΅λ•Œλ§Œ μ‚¬μš©ν• μˆ˜ 있음) πŸ“Œ


πŸ’‘ 검색에 κ΅­κ°€ 와 μž₯λ₯΄ λ„£κΈ° 

 πŸŽ£ 1. src>datas>index.js 파일 생성

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: 'μ• λ‹ˆλ©”μ΄μ…˜',
  },
]

🎣 2. Movie.jsx

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
 
728x90

'πŸ’™ React' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[REACT] Instagram _ Log-In  (0) 2022.10.06
[REACT] Naver μ±… 검색  (0) 2022.10.06
[REACT] Modal  (0) 2022.10.06
[REACT] DropDown  (0) 2022.10.06
[REACT] Accordion  (0) 2022.10.06