프로젝트/영화 목록 (Netflix) 앱

영화목록 (Netflix) 앱 4 - 검색, 정렬 구현하기

syleemomo 2021. 11. 23. 03:06
728x90

 

* 검색 구현하기

import React, { useState, useEffect } from 'react'
import { Movie, Loading } from 'components'

import { Input } from 'components'
import './Home.css'

const Home = () => {
    const [loading, setLoading] = useState(true)
    const [movies, setMovies] = useState([])
    const [query, setQuery] = useState('')
    

    useEffect( () => {
        fetch('https://yts.mx/api/v2/list_movies.json?limit=20')
        .then( res => res.json())
        .then( result => {
            const {data: {movies}} = result
            console.log(movies)
            setLoading(false)
            setMovies(movies)
        })
    }, [])

    const handleChange = (e) => {
        const { value } = e.target
        setQuery(value)
    }

    const homeUI = movies
                        .filter(movie => {
                            const title = movie.title.toLowerCase()
                            const genres = movie.genres.join(' ').toLowerCase()
                            const q = query.toLowerCase()
                        
                            return title.includes(q) || genres.includes(q)
                        })
                        .map(movie => <Movie 
                                        key={movie.id} 
                                        title={movie.title} 
                                        genres={movie.genres} 
                                        cover={movie.medium_cover_image} 
                                        summary={movie.summary}
                                       />
                                    )

    return (
        <>
            {loading? <Loading/>: <div className='Home-container'>
                                    <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
                                    <div className='Home-movies'>{homeUI}</div>
                                  </div>}
        </>
    )
}

export default Home

Home.js 파일을 위와 같이 수정하자!

const [query, setQuery] = useState('')

검색 키워드를 업데이트하기 위하여 리액트 훅을 사용한다.

const handleChange = (e) => {
    const { value } = e.target
    setQuery(value)
}

사용자가 입력한 키워드로 입력창 화면을 설정하기 위하여 리액트 훅을 사용한다. 

const homeUI = movies
                        .filter(movie => {
                            const title = movie.title.toLowerCase()
                            const genres = movie.genres.join(' ').toLowerCase()
                            const q = query.toLowerCase()
                        
                            return title.includes(q) || genres.includes(q)
                        })
                        .map(movie => <Movie 
                                        key={movie.id} 
                                        title={movie.title} 
                                        genres={movie.genres} 
                                        cover={movie.medium_cover_image} 
                                        summary={movie.summary}
                                       />
                                    )

사용자가 입력한 키워드가 영화 제목이나 장르에 포함되어 있으면 해당 영화들만 필터링해서 보여준다.

<>
    {loading? <Loading/>: <div className='Home-container'>
                            <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
                            <div className='Home-movies'>{homeUI}</div>
                          </div>}
</>

 영화를 검색하기 위하여 Input 컴포넌트를 사용하였다. 

 

* 정렬 구현하기

import React from 'react'
import './Movie.css'

const Movie = ({ title, genres, cover, summary, year }) => {
    return (
        <div className='movie-container'>
            <img src={cover} alt={title}></img>
            <h3>{title} ({year})</h3>
            <h4>{genres.join(" ")}</h4>
        </div>
    )
}

export default Movie

Movie.js 파일을 위와 같이 수정한다. year 속성이 추가되었다. 

import React, { useState, useEffect } from 'react'
import { Movie, Loading } from 'components'

import { Input, Button } from 'components'
import './Home.css'

const Home = () => {
    const [loading, setLoading] = useState(true)
    const [movies, setMovies] = useState([])
    const [query, setQuery] = useState('')
    const [isSorted, setIsSorted] = useState(-1)
    

    useEffect( () => {
        fetch('https://yts.mx/api/v2/list_movies.json?limit=20')
        .then( res => res.json())
        .then( result => {
            const {data: {movies}} = result
            console.log(movies)
            setLoading(false)
            setMovies(movies)
        })
    }, [])

    const handleChange = (e) => {
        const { value } = e.target
        setQuery(value)
    }

    const sortByYear = (e) => {
        setIsSorted(isSorted * -1)
    }

    const homeUI = movies
                        .filter(movie => {
                            const title = movie.title.toLowerCase()
                            const genres = movie.genres.join(' ').toLowerCase()
                            const q = query.toLowerCase()
                        
                            return title.includes(q) || genres.includes(q)
                        })
                        .sort( (a, b) => {
                            return (b.year - a.year) * isSorted;
                        })
                        .map(movie => <Movie 
                                        key={movie.id} 
                                        title={movie.title} 
                                        genres={movie.genres} 
                                        cover={movie.medium_cover_image} 
                                        summary={movie.summary}
                                        year={movie.year}
                                       />
                                    )

    return (
        <>
            {loading? <Loading/>: <div className='Home-container'>
                                    <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
                                    <Button handleClick={sortByYear}>정렬</Button>
                                    <div className='Home-movies'>{homeUI}</div>
                                  </div>}
        </>
    )
}

export default Home

Home.js 파일을 위와 같이 수정하자!

import { Input, Button } from 'components'

영화를 정렬하기 위하여 버튼 컴포넌트를 임포트한다.

const [isSorted, setIsSorted] = useState(-1)

정렬 버튼 클릭에 따라 isSorted 상태를 토글시키기 위하여 리액트 훅을 사용한다. 

const sortByYear = (e) => {
    setIsSorted(isSorted * -1)
}

정렬 버튼을 클릭할때마다 isSorted 상태가 -1 에서 1로 바뀌거나 1 에서 -1 로 바뀐다.

const homeUI = movies
                        .filter(movie => {
                            const title = movie.title.toLowerCase()
                            const genres = movie.genres.join(' ').toLowerCase()
                            const q = query.toLowerCase()
                        
                            return title.includes(q) || genres.includes(q)
                        })
                        .sort( (a, b) => {
                            return (b.year - a.year) * isSorted;
                        })
                        .map(movie => <Movie 
                                        key={movie.id} 
                                        title={movie.title} 
                                        genres={movie.genres} 
                                        cover={movie.medium_cover_image} 
                                        summary={movie.summary}
                                        year={movie.year}
                                       />
                                    )

배열 요소들이 객체로 이루어진 경우 위와 같이 sort 메서드를 사용하여 정렬할 수 있다. isSorted 상태가 토글되므로 최신순, 과거순으로 정렬이 된다. 정렬을 위하여 무비 데이터의 year 프로퍼티를 사용하였다. 

<div className='Home-container'>
  <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
  <Button handleClick={sortByYear}>정렬</Button>
  <div className='Home-movies'>{homeUI}</div>
</div>

정렬 버튼을 추가하였다. 

 

* 현재까지의 작업 화면

사용자 등록 화면
로그인 화면
로딩 화면
홈화면 

 

728x90