React - Router - Practice Football Player List

화이티 ·2023년 12월 20일
0

react

목록 보기
9/11

1. Player.css

*{
    padding: 0;
    margin: 0;
}
h1{
    font-size: 5rem;
    margin: 5% 0;
}
.main-container{
    display: flex;
    flex-direction: column;
    align-items: center;
}
.main-container>a{
    font-size: 1.5em;
    font-weight: bold;
    text-decoration: none;
    color: black;
    background-color: lightgray;
    padding: 20px 30px;
    border-radius: 20px;
}
.list-container{
    display: flex;
    flex-direction: column;
    align-items: center;
}
.list-item{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
    cursor: pointer;
}
.item-container{
    display: flex;
    flex-direction: column;
    align-items: center;
    background: linear-gradient(320deg, blue , red);
    color: white;
    font-size: 1.2rem;
    font-weight: bold;
    width: 27.5%;
    padding: 2%;
    margin: 0.5%;
}
img{
    width: 100%;
    margin-bottom: 5%;
    /* border-radius: 50%; */
}
table{
    text-align: center;
    width: 100%;
}
td{
    background-color: rgba(255, 255, 255, 0.5);
    color: black;
    padding: 2.5% 0;
}
tr>td:nth-child(1){
    width: 30%;
}
tr>td:nth-child(2){
    width: 70%;
}

2. Player.jsx

import React from 'react'
import { useState } from 'react';
import { Routes, Route } from 'react-router-dom';
import Main from './components/Main';
import List from './components/List';
import Detail from './components/Detail';
import './player.css'
const Player = () => {
    /**
     * componet 생성 및 리우팅 설정
     * - 메인페이지:Main.jsx => /
 
     * 리수트페이지: List.jsx -> /list
     * 상세페이지: Detail.jsx -> /detail
     * 
     */

    const [list, setList]= useState([]);
    return (
     
      <div className='container'>
     
      
       <Routes>
          <Route path='/' element={<Main/>}></Route>
          <Route path ='/list' element = {<List list ={list} setList={setList}/>}/>
          <Route path ='/detail/:num' element = {<Detail list ={list}/>}/>
        
       </Routes>
  
   
      </div>
    
    );
  }
export default Player

3. index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
//import App from './App';
import App from './Player.jsx'
import reportWebVitals from '../../project06/src/reportWebVitals';
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
reportWebVitals();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

4. Folder public → Player.json

{
    "list" : [
        {
            "name" : "조규성",
            "position" : "FW",
            "age" : 1998,
            "height" : 189,
            "weight" : 82,
            "team" : "FC 미트윌란",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207345228338.jpg"
        }, {
            "name" : "나상호",
            "position" : "MF",
            "age" : 1996,
            "height" : 173,
            "weight" : 70,
            "team" : "FC서울",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207313338443.jpg"
        } , {
            "name" : "손흥민",
            "position" : "MF",
            "age" : 1992,
            "height" : 183,
            "weight" : 78,
            "team" : "토트넘",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207324860557.jpg"
        } , {
            "name" : "황인범",
            "position" : "MF",
            "age" : 1996,
            "height" : 177,
            "weight" : 70,
            "team" : "올림피아코스",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207341162100.jpg"
        } , {
            "name" : "설영우",
            "position" : "DF",
            "age" : 1998,
            "height" : 180,
            "weight" : 72,
            "team" : "울산현대",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2023&name=%25EC%2582%25AC%25EC%25A7%2584_2023032713492058375.jpg"
        } , {
            "name" : "이기제",
            "position" : "DF",
            "age" : 1991,
            "height" : 176,
            "weight" : 68,
            "team" : "수원삼성",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2023&name=%25EC%2582%25AC%25EC%25A7%2584_202303211104076484.jpg"
        } , {
            "name" : "안현범",
            "position" : "MF",
            "age" : 1994,
            "height" : 178,
            "weight" : 72,
            "team" : "제주유나이티드",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2023&name=%25EC%2582%25AC%25EC%25A7%2584_2023061611424516588.jpg"
        } , {
            "name" : "이강인",
            "position" : "MF",
            "age" : 2001,
            "height" : 174,
            "weight" : 72,
            "team" : "파리 생제르맹 FC",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207332743807.jpg"
        } , {
            "name" : "이재성",
            "position" : "MF",
            "age" : 1992,
            "height" : 180,
            "weight" : 70,
            "team" : "FSV 마인츠05",
            "imgSrc" : "https://www.joinkfa.com/generate/CommonFile/ImageView.do?path=NAT/2022&name=%25EC%2582%25AC%25EC%25A7%2584_2022092207333993248.jpg"
        }
    ]
}

5. Src → Folder components

Main.jsx

import React from 'react'
import {Link} from 'react-router-dom'
const Main = () => {
  return (
    <div className='main-container'>

      
<img src = "https://img.kfa.or.kr/main_banner/169743771453908.jpg"  alt = "" width = '100%'/>
      <Link to = '/list'>Player List</Link> 

    </div>
  )
}

export default Main

List.jsx

import React, { useEffect } from 'react'
import Item from './Item'
import axios from 'axios'

const List = ({list,setList}) => {

useEffect(()=>{
    axios
    .get('http://localhost:3000/player.json')
    .then((res)=>{setList(res.data.list)})

},[])
console.log(list);
  return (

    <div className='list-container'>
        <h1></h1>
        <div className='list-item'>
            {list.map((item,index)=>
           <Item key = {index} item ={item} index = {index}/>
           )}
        </div>

    </div>
  )
}

export default List

Item.jsx

import React from 'react'
import { useNavigate } from 'react-router-dom';


const Item = ({item,index}) => {

    const nav = useNavigate();
  return (
    <div className='item-container' onClick={()=>{nav(`/detail/${index}`)}}>
<img src = {item.imgSrc} alt = "" width = "100px"/>
<table>
    <tbody>
        <tr>
            <td>Name</td>
            <td>{item.name}</td>
        </tr>
        <tr>
            <td>position</td>
            <td>{item.position}</td>
        </tr>
        <tr>
            <td>age</td>
            <td>{item.age}년생 ({2023-item.age} years old)</td>
        </tr>
        <tr>
            <td>height, weight</td>
            <td>{item.height}cm, {item.weight}kg </td>
        </tr>
        <tr>
            <td>team</td>
            <td>{item.team}</td>
        </tr>
    </tbody>
</table>
    </div>
  )
}

export default Item

Detail.jsx

import React from 'react'
import { useParams, Link } from 'react-router-dom'
const Detail = ({list}) => {
  let {num} = useParams();

  return (
    <div className='item-container'>
   
    <div className='img'>
      <img src = {list[num].imgSrc} alt = "" width ="100px"></img>
    </div>
    <div className='detail-text'></div>
   
    <table>
    <tbody>
    <tr>
            <td>Name</td>
            <td>{list[num].name}</td>
        </tr>
        <tr>
            <td>position</td>
            <td>{list[num].position}</td>
        </tr>
        <tr>
            <td>age</td>
            <td>{list[num].age}년생 ({2023-list[num].age} years old)</td>
        </tr>
        <tr>
            <td>height, weight</td>
            <td>{list[num].height}cm, {list[num].weight}kg </td>
        </tr>
        <tr>
            <td>team</td>
            <td>{list[num].team}</td>
        </tr>
   </tbody>
   </table>
    <p>
    <Link to ='/list'>목록으로 돌아가기</Link>
    </p>
    
    </div>
       
  )
}

export default Detail

profile
열심히 공부합시다! The best is yet to come! 💜

0개의 댓글