2swan
React Router 예제(Class 방식) 본문
App.js
import {BrowserRouter, Route, Routes} from "react-router-dom"
import './App.css';
import Home from './routers/Home';
import About from "./routers/About";
import Navigation from "./components/Navigation";
function App() {
return (
<BrowserRouter>
<Navigation/>
<Routes>
<Route path={"/"} element={<Home/>}></Route>
<Route path={"/about"} element={<About/>}></Route>
</Routes>
</BrowserRouter>
);
}
export default App;
App.css
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #eff3f7;
height: 100%;
}
Movie.css
// components 폴더
.movies .movie {
background-color: white;
margin-bottom: 70px;
font-weight: 300;
padding: 20px;
border-radius: 5px;
color: #adaeb9;
box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3),
0 -6px 16px -6px rgba(0, 0, 0, 0.025);
}
.movies .movie a {
display: grid;
grid-template-columns: minmax(150px, 1fr) 2fr;
grid-gap: 20px;
text-decoration: none;
color: inherit;
}
.movie img {
position: relative;
top: -50px;
max-width: 150px;
width: 100%;
margin-right: 30px;
box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3),
0 -12px 36px -8px rgba(0, 0, 0, 0.025);
}
.movie .movie__title,
.movie .movie__year {
margin: 0;
font-weight: 300;
}
.movie .movie__title {
margin-bottom: 5px;
font-size: 24px;
color: #2c2c2c;
}
.movie .movie__genres {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
margin: 5px 0px;
}
.movie__genres li,
.movie .movie__year {
margin-right: 10px;
font-size: 14px;
}
Movie.js
// components 폴더
import { Component } from "react";
import './Movie.css'
class Movie extends Component{
render(){
const {title, year, summary, poster, genres} = this.props
return(
<div className="movie">
<img src={poster} alt={title} title={title}/>
<div className="movie_data">
<h3 className="movie_title">{title}</h3>
<h5 className="movie_year">{year}</h5>
<ul className="moive_genres">
{
genres.map((genre,index)=>{
return(
<li key={index}>
{genre}
</li>
)
})
}
</ul>
<p>{summary.slice(0,100)}...</p>
</div>
</div>
)
}
}
export default Movie;
Navigation.css
// components 폴더
.nav {
z-index: 1;
position: fixed;
top: 50px;
left: 10px;
display: flex;
flex-direction: column;
background-color: white;
padding: 10px 20px;
box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3),
0 -6px 16px -6px rgba(0, 0, 0, 0.025);
border-radius: 5px;
}
@media screen and (max-width: 1090px) {
.nav {
left: initial;
top: initial;
bottom: 0px;
width: 100%;
}
}
.nav a {
text-decoration: none;
color: #0008fc;
text-transform: uppercase;
font-size: 12px;
text-align: center;
font-weight: 600;
}
.nav a:not(:last-child) {
margin-bottom: 20px;
}
Navigation.js
// components 폴더
import { Link } from "react-router-dom";
import "./Navigation.css"
function Navigation(){
return(
<div className="nav">
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</div>
)
}
export default Navigation;
About.css
// routers 폴더
.about__container {
box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3),
0 -6px 16px -6px rgba(0, 0, 0, 0.025);
padding: 20px;
border-radius: 5px;
background-color: white;
margin: 0 auto;
margin-top: 100px;
width: 100%;
max-width: 400px;
font-weight: 300;
}
.about__container span:first-child {
font-size: 20px;
}
.about__container span:last-child {
display: block;
margin-top: 10px;
}
About.js
// routers 폴더
import { Component } from "react";
import './About.css'
class About extends Component{
render(){
return(
<div className="about_container">
<span>About</span>
<span>2023</span>
</div>
)
}
}
export default About;
Home.css
// routers 폴더
.container {
height: 100%;
display: flex;
justify-content: center;
}
.loader {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-weight: 300;
}
.movies {
display: grid;
grid-template-columns: repeat(2, minmax(400px, 1fr));
grid-gap: 100px;
padding: 50px;
width: 80%;
padding-top: 70px;
}
@media screen and (max-width: 1090px) {
.movies {
grid-template-columns: 1fr;
width: 100%;
}
}
Home.js
// routers 폴더
import React, {Component} from 'react';
import axios from 'axios';
import './Home.css'
import Movie from '../components/Movie';
class Home extends Component{
state ={
isLoading : true,
movies : []
}
//첫 번째 방법
// getMoives = async() => {
// const{
// data : {
// data: {movies}
// }
// } = await axios.get('https://yts.mx/api/v2/list_movies.json?sort_by=rating')
// console.log(movies)
// this.setState({movies, isLoading:false})
// }
//두 번째 방법
getMoives =()=>{
fetch('https://yts.mx/api/v2/list_movies.json?sort_by=rating')
.then((res)=>res.json())
.catch(err => console.log(err))
.then((res)=>{
console.log(res.data.movies)
this.setState({movies: res.data.movies, isLoading:false})
})
}
componentDidMount(){
this.getMoives();
}
render(){
const {isLoading, movies} = this.state
return(
<section className='container'>
{
isLoading ? (
<div className='loader'>
<span>isLoading</span>
</div>
) : (
<div className='movies'>
{
movies.map((movie)=>{
return(
//사진, title, year, genres, summary
<Movie key={movie.id}
year = {movie.year}
title = {movie.title}
summary = {movie.summary}
poster = {movie.medium_cover_image}
genres = {movie.genres}
/>
)
})
}
</div>
)
}
</section>
)
}
}
export default Home;
MovieView.css
// routers 폴더
.movie__container {
box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3),
0 -6px 16px -6px rgba(0, 0, 0, 0.025);
padding: 20px;
border-radius: 5px;
background-color: white;
margin: 0 auto;
margin-top: 100px;
width: 100%;
max-width: 400px;
font-weight: 300;
}
.movie__container span:first-child {
font-size: 20px;
}
.movie__container span:last-child {
display: block;
margin-top: 10px;
}
.movie img {
position: relative;
top: -50px;
max-width: 150px;
width: 100%;
margin-right: 30px;
box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3),
0 -12px 36px -8px rgba(0, 0, 0, 0.025);
}
.movie .movie__title,
.movie .movie__year {
margin: 0;
font-weight: 300;
}
.movie .movie__title {
margin-bottom: 5px;
font-size: 24px;
color: #2c2c2c;
}
.movie .movie__genres {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
margin: 5px 0px;
}
.movie__genres li,
.movie .movie__year {
margin-right: 10px;
font-size: 14px;
}
Navigation.css
// routers 폴더
.nav {
z-index: 1;
position: fixed;
top: 50px;
left: 10px;
display: flex;
flex-direction: column;
background-color: white;
padding: 10px 20px;
box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3),
0 -6px 16px -6px rgba(0, 0, 0, 0.025);
border-radius: 5px;
}
@media screen and (max-width: 1090px) {
.nav {
left: initial;
top: initial;
bottom: 0px;
width: 100%;
}
}
.nav a {
text-decoration: none;
color: #0008fc;
text-transform: uppercase;
font-size: 12px;
text-align: center;
font-weight: 600;
}
.nav a:not(:last-child) {
margin-bottom: 20px;
}
'Programming > React' 카테고리의 다른 글
React Login 예제 (0) | 2023.10.14 |
---|---|
React Router 예제(함수 방식) (0) | 2023.09.12 |
React DB 연결(Mybatis) (0) | 2023.09.11 |
React 추가, 삭제(Mybatis) (0) | 2023.09.11 |
React DB 연결(JPA) (0) | 2023.09.11 |