ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 영화목록 (netflix) 앱 2 - 라우터 구현하기
    프로젝트/영화 목록 (Netflix) 앱 2021. 11. 22. 22:43
    728x90

     

    * 프로젝트 폴더 생성하기

    npx create-react-app netflix

     

    * 리액트 라우터 설치하기 

    cd netflix
    npm install react-router-dom

     

    리액트 라우터 URL 주소 이동하기

     

    how to use history instance while using react routers v6?

    I'm using react-router v6 and I have to use history instance. I've installed it using yarn add history react-router-dom@next One way of using history instance I guess it must be with v5 is to use

    stackoverflow.com

     

     

    * 라우터 기능 추가하기

    import React from "react"
    import ReactDOM from "react-dom"
    import { BrowserRouter } from "react-router-dom"
    
    const App = () => {
      return (
        <div>Hello React !</div>
      );
    };
      
    ReactDOM.render(<BrowserRouter>
                      <App />
                    </BrowserRouter>, 
                    document.getElementById("root"));

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

    import { BrowserRouter } from "react-router-dom"

    라우터 기능을 추가하기 위하여 react-router-dom 라이브러리에서 BrowserRouter 컴포넌트를 임포트한다. 

    ReactDOM.render(<BrowserRouter>
                      <App />
                    </BrowserRouter>, 
                    document.getElementById("root"));

    App 컴포넌트를 BrowserRouter 컴포넌트로 감싸준다. 

     

    * 페이지 생성하기 - 사용자 등록 페이지, 사용자 로그인 페이지, 홈페이지

    src 폴더 하위에 pages 폴더를 생성한다. pages 폴더 하위에 아래와 같은 파일들을 생성하고 코드를 구현하자!

    import React from 'react'
    
    const Register = () => {
        return (
            <div>Register</div>
        )
    }
    
    export default Register

    Register.js 파일을 생성하고 위와 같이 작성하자!

    import React from 'react'
    
    const Login = () => {
        return (
            <div>Login</div>
        )
    }
    
    export default Login

    Login.js 파일을 생성하고 위와 같이 작성하자!

    import React from 'react'
    
    const Home = () => {
        return (
            <div>Home</div>
        )
    }
    
    export default Home

    Home.js 파일을 생성하고 위와 같이 작성하자!

    export { default as Register } from './Register'
    export { default as Login } from './Login'
    export { default as Home } from './Home'

    index.js 파일을 생성하고 위와 같이 작성하자!

     

    * 페이지 라우팅하기

    import React from "react"
    import ReactDOM from "react-dom"
    import { BrowserRouter, Route, Routes } from "react-router-dom"
    import { Register, Login, Home } from './pages'
    
    
    const App = () => {
      return (
        <div>
          <Routes>
              <Route path='/' element={<Register/>}/>
              <Route path="/login" element={<Login/>}/>
              <Route path="/home" element={<Home/>}/>
          </Routes>
        </div>
      );
    };
      
    ReactDOM.render(<BrowserRouter>
                      <App />
                    </BrowserRouter>, 
                    document.getElementById("root"));

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

    import { BrowserRouter, Route, Routes } from "react-router-dom"

    페이지 라우팅 기능을 적용하기 위하여 react-router-dom 라이브러리에서 BrowserRouter, Route, Routes 컴포넌트를 임포트한다. 

    import { Register, Login, Home } from './pages'

    pages 폴더 내부의 페이지 컴포넌트들을 임포트한다. 

    <div>
        <Routes>
            <Route path='/' element={<Register/>}/>
            <Route path="/login" element={<Login/>}/>
            <Route path="/home" element={<Home/>}/>
        </Routes>
      </div>

    Routes, Route 컴포넌트를 사용하여 URL 경로에 따라 해당 페이지를 보여줄 수 있도록 설정한다. 웹서비스가 시작하면 사용자 등록을 위한 페이지가 처음으로 보여진다. /login 경로에 접속하면 로그인 화면을 보여준다. /home 경로에 접속하면 홈 화면을 보여준다.

     

    * Input 컴포넌트 만들기

    src 폴더 하위에 components 폴더를 생성한다.  components 폴더 하위에 아래와 같은 파일들을 생성하고 코드를 구현하자!

    import React from 'react'
    
    const Input = ({ name, type, placeholder, value, onChange}) => {
        return (
            <input name={name} type={type} placeholder={placeholder} value={value} onChange={onChange}/>
        )
    }
    
    export default Input

    Input.js 파일을 위와 같이 생성하자!

    export { default as Input } from './Input'

    index.js 파일을 위와 같이 생성하자!

     

    * Register 페이지에서 Input 사용하기 

    import React, { useState } from 'react'
    
    import { Input } from '../components'
    
    const Register = () => {
        const [id, setId] = useState('')
        const [password, setPassword] = useState('')
    
        const handleChange = (e) => {
            const { name, value } = e.target
            name === 'id' ? setId(value) : setPassword(value)
            console.log(name, value)
        }
        return (
            <div>
                <Input name='id' type='text' placeholder='Type ID ...' value={id} onChange={handleChange}/><br/>
                <Input name='password' type='password' placeholder='Type PASSWORD ...' value={password} onChange={handleChange}/>
            </div>
        )
    }
    
    export default Register

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

    사용자 등록을 위한 Input 컴포넌트를 임포트하고 사용한다. 리액트 훅 (state hook) 을 사용하여 사용자 입력을 처리한다. 

     

    * 사용자 정보의 유무에 따라 다른 페이지 보여주기 - Register 페이지

    import React, { useState } from 'react'
    import { useNavigate } from "react-router-dom"
    
    import { Input } from '../components'
    
    const Register = () => {
        const [id, setId] = useState('')
        const [password, setPassword] = useState('')
        const navigate = useNavigate()
    
        const handleChange = (e) => {
            const { name, value } = e.target
            name === 'id' ? setId(value) : setPassword(value)
            console.log(name, value)
        }
        const handleRegister = () => {
            if(JSON.parse(sessionStorage.getItem('user'))){
                navigate('/login')
            }else{
                sessionStorage.setItem('user', JSON.stringify({ id, password }))
                navigate('/home')
            } 
        }
        return (
            <div>
                <Input name='id' type='text' placeholder='Type ID ...' value={id} onChange={handleChange}/><br/>
                <Input name='password' type='password' placeholder='Type PASSWORD ...' value={password} onChange={handleChange}/><br/>
                <button onClick={handleRegister}>Register</button>
            </div>
        )
    }
    
    export default Register

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

    import { useNavigate } from "react-router-dom"

    특정 페이지로 이동 (redirect) 하기 위하여 react-router-dom 라이브러리에서 useNavigate 함수를 임포트한다. 

    const navigate = useNavigate()

    useNavigate 함수를 실행하면 navigate 함수를 반환한다. 해당 함수는 다른 URL 경로로 이동할 수 있는 기능을 제공한다.

    const handleRegister = () => {
          if(JSON.parse(sessionStorage.getItem('user'))){ // 사용자 정보가 있는 경우
              navigate('/login')
          }else{
              sessionStorage.setItem('user', JSON.stringify({ id, password })) // 사용자 정보 등록
              navigate('/home')
          } 
      }

    사용자가 등록 정보를 입력하고 버튼을 클릭하면 해당 함수가 실행된다. 사용자 정보가 이미 등록되어 있으면 로그인 화면으로 안내한다. 그렇지 않으면 사용자 정보를 등록하고 홈화면으로 이동한다. navigate 의 인자로 이동하고자 하는 URL 경로를 설정하면 해당 경로로 이동한다. 

    브라우저 API 인 세션 스토리지를 사용하여 사용자 정보를 조회하고 등록한다. 

     

    * 로그인 기능 구현하기 - Login 페이지 

    import React, { useState } from 'react'
    import { useNavigate } from "react-router-dom"
    
    import { Input } from '../components'
    
    const Login = () => {
        const [id, setId] = useState('')
        const [password, setPassword] = useState('')
        const navigate = useNavigate()
    
        const handleChange = (e) => {
            const { name, value } = e.target
            name === 'id' ? setId(value) : setPassword(value)
            console.log(name, value)
        }
        const handleLogin = () => {
            const user = JSON.parse(sessionStorage.getItem('user'))
            if(id === user.id && password === user.password){
                navigate('/home')
            }else{
                alert('You gaved wrong id or password !')
            } 
        }
        return (
            <div>
                <Input name='id' type='text' placeholder='Type ID ...' value={id} onChange={handleChange}/><br/>
                <Input name='password' type='password' placeholder='Type PASSWORD ...' value={password} onChange={handleChange}/><br/>
                <button onClick={handleLogin}>Login</button>
            </div>
        )
    }
    
    export default Login

    Login.js 파일을 위와 같이 작성하자!

    const handleLogin = () => {
          const user = JSON.parse(sessionStorage.getItem('user'))
          if(id === user.id && password === user.password){
              navigate('/home')
          }else{
              alert('You gaved wrong id or password !')
          } 
      }

    Register 화면과 사용자 입력 처리 부분은 동일하다. 사용자가 로그인 정보를 입력하고 버튼을 클릭했을때 실제 사용자 정보와 입력한 정보가 일치하면 /home 경로로 이동한다. 그렇지 않으면 경고창을 띄워서 사용자에게 다시 한번 로그인 정보를 입력하도록 안내한다. 

     

    * 홈화면에 영화목록 보여주기

    components 폴더에 다음 파일을 추가한다. 

    import React from 'react'
    
    const Movie = ({ title, genres, cover, summary }) => {
        return (
            <div>
                <img src={cover} alt={title}></img>
                <h3>{title}</h3>
                <h4>{genres.join(" ")}</h4>
                <p>{summary}</p>
            </div>
        )
    }
    
    export default Movie

    Movie.js 파일을 위와 같이 생성하자!

    export { default as Input } from './Input'
    export { default as Movie } from './Movie'

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

    import React, { useState, useEffect } from 'react'
    import { Movie } from '../components'
    
    const Home = () => {
        const [loading, setLoading] = useState(true)
        const [movies, setMovies] = useState([])
    
        useEffect( () => {
            fetch('https://yts.mx/api/v2/list_movies.json?limit=12')
            .then( res => res.json())
            .then( result => {
                const {data: {movies}} = result
                console.log(movies)
                setLoading(false)
                setMovies(movies)
            })
        }, [])
    
        const homeUI = movies.map(movie => <Movie 
                                            key={movie.id} 
                                            title={movie.title} 
                                            genres={movie.genres} 
                                            cover={movie.medium_cover_image} 
                                            summary={movie.summary}/>
                                        )
    
        return (
            <div>
                {loading? 'Loading ...': homeUI}
            </div>
        )
    }
    
    export default Home

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

    리액트 훅 (state hook, effect hook) 을 사용하여 OPEN API 서버에서 무비 데이터를 가져와서 홈화면에 디스플레이한다.

     

    * 로딩화면 구현하기

    먼저 src 폴더 하위에 assets 폴더를 생성한다. assets 폴더 하위에 images 폴더를 생성한다. images 폴더에 loading.gif 를 추가한다. 

    components 폴더에 다음 파일을 추가한다. 

    import React from 'react'
    import loadingImg from '../assets/images/loading.gif'
    
    const Loading = () => {
        return (
            <div>
                <img src={loadingImg} alt='loading-img'></img>
            </div>
        )
    }
    
    export default Loading

    Loading.js 파일을 위와 같이 생성하자!

    export { default as Input } from './Input'
    export { default as Movie } from './Movie'
    export { default as Loading } from './Loading'

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

    import React, { useState, useEffect } from 'react'
    import { Movie, Loading } from '../components'
    
    const Home = () => {
        const [loading, setLoading] = useState(true)
        const [movies, setMovies] = useState([])
    
        useEffect( () => {
            fetch('https://yts.mx/api/v2/list_movies.json?limit=12')
            .then( res => res.json())
            .then( result => {
                const {data: {movies}} = result
                console.log(movies)
                setLoading(false)
                setMovies(movies)
            })
        }, [])
    
        const homeUI = movies.map(movie => <Movie 
                                            key={movie.id} 
                                            title={movie.title} 
                                            genres={movie.genres} 
                                            cover={movie.medium_cover_image} 
                                            summary={movie.summary}
                                           />
                                        )
    
        return (
            <div>
                {loading? <Loading/>: homeUI}
            </div>
        )
    }
    
    export default Home

     

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

    import { Movie, Loading } from '../components'

    Loading 컴포넌트를 임포트한다. 

    <div>
        {loading? <Loading/>: homeUI}
    </div>

    Loading 컴포넌트를 사용해서 로딩화면을 디스플레이한다. 

     

    728x90
Designed by Tistory.