라우트 실습1
상품 목록페이지에서 상품을 누르면 상품 상세 정보 페이지
메인 창
상품목록 페이지
상품을 누르면
상품 상세 페이지가 뜸
import logo from './logo.svg';
import './App.css';
import Header from './components/Header';
import Footer from './components/Footer';
import { Routes,Route } from 'react-router-dom';
import Main from './components/Main';
import ProductDetail from './components/ProductDetail';
import ProductList from './components/ProductList';
import { useState } from 'react';
function App() {
const[list,setList] = useState([]);
return (
<div className="container">
<Header/>
<Routes>
<Route path='/' element={<Main/>}> 메인</Route>
<Route path='/List' element={<ProductList list={list} setList={setList}/>}></Route>
<Route path='/detail/:num' element={<ProductDetail list={list}/>}> 메인</Route>
</Routes>
<Footer/>
</div>
);
}
export default App;
ProductList에 list와 setList값,
ProductDetail에는 list값 넘겨주기
import React from 'react'
import { Link } from 'react-router-dom'
const Header = () => {
return (
<div className='header-container'>
<Link to='/'>Kream 👓</Link>
<Link to='/list'>상품목록 </Link>
</div>
)
}
export default Header
import React from 'react'
const Footer = () => {
return (
<div className='footer-container'>
<strong>크림 주식회사</strong> · 대표 김창욱사업자등록번호 : 570-88-01618
</div>
)
}
export default Footer
import React from 'react'
const Main = () => {
return (
<div className='main-container'>
<div className='main-text'>
<h1>
한정판 거래 플랫폼, KREAM
</h1>
</div>
<div className='main-image'>
<img src="https://cloudfront-ap-northeast-1.images.arcpublishing.com/chosunbiz/IVMTVZH5PBBABK627VRILTVTMY.jpg" />
</div>
</div>
)
}
export default Main
import React, { useEffect } from 'react'
import axios from 'axios'
import ProductItem from './ProductItem'
const ProductList = ({list,setList}) => {
/*
(1) public 안 bestList.json 데이터 접근
=> axios, useEffect이용
(2) 가지고 온 데이터 list에 세팅
=> useNavigate 사용
=> 상품별 고유번호 index 사용 : /detail/1, detail1/2
*/
useEffect(()=>{
axios
.get('http://localhost:3000/bestList.json')
.then(res=>{
console.log(res.data.list);
setList(res.data.list)})
},[])
console.log("list",list);
return (
<div className='main-container'>
{list.map((item,index)=>
<ProductItem key={index} item={item} index={index}/>
)}
<div onClick={()=>{
}}></div>
</div>
)
}
export default ProductList
**첫 렌더링 때 axios 이용하여 public 파일에 json파일 가져오기!!
list를 map으로 돌리면서 ProductItem에 list정보 props로 넘겨주기**
import React from 'react'
import { useNavigate } from 'react-router-dom';
const ProductItem = ({item,index}) => {
console.log(item,index);
/*
해당 아이템 div을 클릭 했을 때,
아이템에 대한 상세페이지(ProductDetail)로 이동
*/
const nav = useNavigate();
return (
<div className='product-container'
onClick={()=>{
nav(`/detail/${index}`)
}}>
<img src={item.src}/>
<p>{item.title}</p>
<p>{item.price}원</p>
</div>
)
}
export default ProductItem
list값(item,index) props로 가져옴
naviate-> 조건을 걸 수 있다
클릭시 해당 상품 상세 정보 페이지로 넘어감
import React from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
const ProductDetail = ({list}) => {
let {num} = useParams();
let nav = useNavigate();
return (
<div className='main-container'>
<div className='product-container detail-container'>
<div className='datail-image'>
<img src={list[num].src} alt="" />
</div>
<div className='detail-text'>
<h4>{list[num].title}</h4>
<p>
<span>{list[num].price}원</span>
<span>{list[num].delivery ==="free"? "무료배송" : "배송비 :" + list[num].delivery+"원"}</span>
</p>
<Link to='/List'>목록으로 돌아가기</Link>
</div>
</div>
</div>
)
}
export default ProductDetail
useParams를 이용해 해당 파라미터 정보를 가져와서 num에 저장
해당하는 num의 상품이 출력!!
라우트 실습1
프로젝트 생성
npx create-react-app project06
npm install axios react-router-dom
BrowserRouter
Routes
Route
각각 임포트
컴포넌트 생성 및 라우팅 설정
-메인페이지 : Main.jsx => /
-리스트페이지 : List.jsx => / list
-상세페이지 : Detail.jsx => /detail
json 데이터 이동 방식
만약 리스트 오류가 가끔씩 나올 때
→ 조건을 걸어주자 list가 있을 때 list.map 돌려주기!!
메인화면
player List를 클릭하면 다음 페이지
해당 선수를 클릭하면
->해당 선수 상세 정보 페이지
Player.json (public)
{
"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"
}
]
}
Player.jsx
import React, { 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 = () => {
// list state초기화
const [list,setList] = useState([]);
return (
<div>
<Routes>
<Route path='/' element={<Main/>}></Route>
<Route path='/list' element={<List list={list} setList={setList}/>}></Route>
<Route path='/detail/:num' element={<Detail list={list}/>}></Route>
</Routes>
</div>
)
}
export default Player
Main.jsx
import React from 'react'
import { Link } from 'react-router-dom'
const Main = () => {
return (
<div className='main-container'>
<img src="https://www.playkfa.com/banner/1957a327-cf91-4a99-8f41-2c95c698dc45.png"
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}) => {
/*
public 안의 json파일 데이터 가져오기
*/
useEffect(()=>{
axios
.get('http://localhost:3000/player.json')
.then((res)=>{
setList(res.data.list)
})
},[])
console.log(list);
// 🎈🎈 React - Spring 연동
useEffect(()=>{
console.log("Spring으로 요청");
// 경로
let url = 'http://localhost:8090/SpringBoot2/PlayerList.do'
// 서버 주소 변경(localhost 부분)
axios
// 어디로 보낼지! blob-> 멀티미디어를 다룰때!
.post(url, {responseType : 'blob'})
.then((res)=>{
console.log(res.data);
setList(res.data)
})
},[])
return (
<div className='list-container'>
<h1>KOREA REPUBLIC</h1>
<div className='list-item'>
{list.map((item,index) => <Item item={item}
key={index} index={index}></Item>)}
</div>
</div>
)
}
export default List
Detail.jsx
import React from 'react'
import { useParams } from 'react-router-dom'
const Detail = ({list}) => {
let {num} = useParams();
return (
<div className='item-container'>
<img src={list[num].imgSrc} alt="" width='100%' />
<table>
<tbody>
<tr>
<td>이름</td>
<td>{list[num].name}</td>
</tr>
<tr>
<td>포지션</td>
<td>{list[num].position}</td>
</tr>
<tr>
<td>나이</td>
<td>{2023-list[num].age}세</td>
</tr>
<tr>
<td>키,몸무게</td>
<td>{list[num].height}cm,{list[num].weight}kg</td>
</tr>
<tr>
<td>팀</td>
<td>{list[num].team}</td>
</tr>
</tbody>
</table>
</div>
)
}
export default Detail
Item.jsx
import React from 'react'
import { useNavigate } from 'react-router-dom'
const Item = ({item,index}) => {
/*
프로필 카드 클릭 시 해당 선수 상세 페이지로 이동
/detail/index
Item.jsx => 클릭 시 경로 이동 (/detail/idex)
Detail.jsx => index 파라미터 설정
Player.jsx => 라우트 경로 추가 (/detail/~)
*/
const nav = useNavigate();
return (
<div className='item-container'
onClick={()=>{
nav(`/detail/${index}`)
}}>
<img src={item.imgSrc} alt="" />
<table>
<tbody>
<tr>
<td>이름</td>
<td>{item.name}</td>
</tr>
<tr>
<td>포지션</td>
<td>{item.position}</td>
</tr>
</tbody>
</table>
</div>
)
}
export default Item
다음 아래는 React - Spring 연동시 코드
→ 데이터를 보내줄 때
->어디로 보낼지! blob-> 멀티미디어를 다룰때!