-
영화목록 (netflix) 앱 2 - 라우터 구현하기프로젝트/영화 목록 (Netflix) 앱 2021. 11. 22. 22:43728x90
* 프로젝트 폴더 생성하기
npx create-react-app netflix
* 리액트 라우터 설치하기
cd netflix npm install react-router-dom
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'프로젝트 > 영화 목록 (Netflix) 앱' 카테고리의 다른 글
영화목록 (Netflix) 앱 5 - 상세페이지 만들기 (0) 2021.11.24 영화목록 (netflix) 앱 번외편 - 사용자 정보 유효성 검증 (0) 2021.11.23 영화목록 (Netflix) 앱 4 - 검색, 정렬 구현하기 (0) 2021.11.23 영화목록 (Netflix) 앱 3 - 스타일링하기 (0) 2021.11.23 영화목록 (Netflix) 앱 1 - 프로젝트 셋팅 및 웹팩(webpack) 설정 (0) 2021.11.22