ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 영화목록 (Netflix) 앱 9 - 홈화면에 영화목록 전체보기 기능 만들기
    프로젝트/영화 목록 (Netflix) 앱 2021. 11. 25. 20:00
    728x90

     

    * 영화목록 전체보기 기능 구현하기

    import React, { useState, useEffect } from 'react'
    import { Link, useNavigate } from 'react-router-dom'
    
    import { Movie, Loading, Input, Button, Menu } 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)
        const [limit, setLimit] = useState(6)
        const navigate = useNavigate()
    
        const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
        console.log(likes)
        
    
        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 updateLikes = (id) => {
            const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
           
            if(likes[id] === null || likes[id] === undefined){
                likes[id] = 0
            }
            likes[id] += 1
            sessionStorage.setItem('likes', JSON.stringify(likes))
        }
    
        const handleRemove = (id) => {
            const moviesFiltered = movies.filter(movie => movie.id !== id)
            setMovies(moviesFiltered)
    
            // likes 리스트에서도 해당 영화에 대한 좋아요 정보 제거
            const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
            delete likes[id]
            sessionStorage.setItem('likes', JSON.stringify(likes))
    
        }
        const displayEntireMovies = () => {
            console.log('display all movies !')
            setLimit(movies.length)
        }
    
        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;
                            })
                            .slice(0, limit)
                            .map(movie =>
                                <div className='movie-item' key={movie.id}  >
                                    <div className='movie-delete' onClick={(e) => handleRemove(movie.id)}>X</div>
                                    <Link 
                                        to='/detail'
                                        state={{ movie }} 
                                        style={{ textDecoration: 'none', color: 'white'}}
                                        onClick={() => updateLikes(movie.id)}
                                    >
                                        
                                        <Movie 
                                                title={movie.title} 
                                                genres={movie.genres} 
                                                cover={movie.medium_cover_image} 
                                                summary={movie.summary}
                                                year={movie.year}
                                                rating={movie.rating}
                                                likes={likes[movie.id]}
                                            />
                                    </Link>
                                </div> 
                                        )
    
        const toRankPage = () => {
            navigate('/recommend', { state: { movies }})
        }
        return (
            <>
                {loading? <Loading/>: <div className='Home-container'>
                                        <Menu>
                                            <Button handleClick={toRankPage}>Rank</Button>
                                        </Menu>
                                        <div className='Home-entire'>
                                            <Button handleClick={displayEntireMovies}>See Entire Movies</Button>
                                        </div>
                                        
                                        <div className='Home-contents'>
                                            <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
                                            <Button handleClick={sortByYear}>정렬</Button>
                                            <div className='Home-movies'>{homeUI}</div>
                                        </div>
                                      </div>}
            </>
        )
    }
    
    export default Home

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

    const [limit, setLimit] = useState(6)

    리액트 훅을 이용하여 처음 홈화면이 나타날때 보여줄 영화의 갯수를 설정한다. 처음 홈화면이 렌더링할때 6개의 영화목록만 보여주도록 한다. 

    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;
        })
        .slice(0, limit)

    limit 값에 따라 보여줄 영화 갯수를 조절할 수 있도록 배열의 slice 메서드를 사용하여 설정한다. 

    <div className='Home-entire'>
        <Button handleClick={displayEntireMovies}>See Entire Movies</Button>
    </div>

    버튼을 클릭하면 전체 영화목록을 보여줄 수 있도록 displayEntireMovies 라는 이벤트핸들러 함수를 연결한다. 

    const displayEntireMovies = () => {
        console.log('display all movies !')
        setLimit(movies.length)
    }

    이벤트핸들러 함수가 실행되면 movies.length 라는 전체 영화 갯수로 limit 값을 업데이트해준다. 

     

    * 영화목록 전체보기 버튼 스타일링하기

    .Home-container{
        background: url('../assets/images/background.jpg');
        width: 100%;
        padding: 30px;
        text-align: center;
        border: 1px solid black;
        position: relative;
    }
    .Home-contents{
        /* border: 5px solid orange; */
        margin-top: 100px;
    }
    .Home-movies{
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        width: 60%;
        margin: 0px auto;
        text-align: center;
    }
    .movie-item{
        position: relative;
    }
    .movie-delete{
        width: 50px;
        height: 50px;
        color: black;
        background: transparent;
        opacity: 0.6;
        position: absolute;
        cursor: pointer;
        top: 10px;
        right: 10px;
        z-index: 1;
        text-align: center;
        line-height: 50px;
        font-weight: bold;
        font-size: 1.5rem;
    }
    .movie-delete:hover{
        background: #a9a9a9;
    }
    .Home-entire{
        position: fixed;
        right: 10px;
        bottom: 10px;
    }

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

    728x90
Designed by Tistory.