ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 영화목록 (Netflix) 앱 4 - 검색, 정렬 구현하기
    프로젝트/영화 목록 (Netflix) 앱 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
Designed by Tistory.