2swan

React Router 예제(Class 방식) 본문

Programming/React

React Router 예제(Class 방식)

2swan 2023. 9. 12. 02:28

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