
메인페이지로 기능은 3가지
1. 가져온 데이터 뿌리기
2. 주문하기 버튼 클릭시 디테일 화면으로
3. 추가상품번호 클릭시 데이터 추가
Home.jsx
import { useSelector } from 'react-redux';
import Card from '../components/Card.jsx';
import { AddShoesList } from '../components/button.jsx';
function Home(){
const shoes = useSelector((state) => state.shoes); // Redux에서 shoes 가져오기
return(
<div className="container">
<div className="row">
{shoes.map((a, i)=>{ // map으로 반복문 돌리기~
return <Card shoes={a} i={i} key={a.id} ></Card> // 만들어둔 Card 컴포넌트 사용하기
})}
{/* 추가상품버튼 */}
<AddShoesList shoes={shoes} />
</div>
</div>
)
}
export default Home
Home에선 호출만 한다.
< Card > 로 자식 컴포넌트를 만들고 props 형태로 shoes를 전달하여 실제로는 Card.jsx에 구현했다.
map은 그냥 반복문으로 뿌려주는 역할
Card.jsx
import { useNavigate } from 'react-router-dom' // 화면전환할때 쓰는 라우터 라이브러리
// 컴포넌트 만들기
function Card(props) { //위에서 쓸 컴포넌트 미리 만들어두기
let navigate = useNavigate()
return (
<div className="col-md-4">
{/* <img src={'https://codingapple1.github.io/shop/shoes' + (props.i+1) + '.jpg'} width="80%" /> */}
<h4>{props.shoes.title}</h4>
<p>{props.shoes.price}</p>
<button className="btn btn-danger" onClick={()=>navigate('/detail/'+props.shoes.id)} >주문하기</button>
</div>
)
}
export default Card
useNavigate 훅을 통해 사용했고 컴퍼넌트 내부에서만 사용 가능하며 전체 페이지 새로고침 없이 동적이 Url 이동이 가능하게 함
App.jsx
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import styled from 'styled-components'; // 스타일드 컴포넌트 라이브러리- 컴포넌트 만들시 스타일 미리 주입 - 편하나 관리가 어려움
import { HomeNavbar } from './components/Navbar.jsx'; //네비
import MyRoutes from './routes/Routes.jsx';
import useReload from './hooks/useReload.js';
function App() {
// 화면 새로고침시 cart에 담아놓은 값 초기화
useReload();
return (
<div>
{/* 홈 - 네비바 */}
<HomeNavbar/>
{/* 메인페이지 - 라우터 */}
<MyRoutes/>
</div>
)
}
export default App
임포트는 여러군데에서 했지만 메인화면 코드는 이게 끝임
여기에는 context api, useState 기능이 사용됨
useState를 이용해 json형태로 가지고온 shoes를 라우터에 보낸 후 화면으로 보냄
useState는 리엑트에서 제공하는 hook 방법
예를 들어
let [shoes, setShoes] = useState(data);
값의 상태를 관리하기 위함
shoes는 데이터가 담긴 변수명
setShoes는 데이터를 수정할 함수명
data는 초기값
data에 값을 shoes에 넣고 이 값을 수정할땐 setShoes를 사용한다.
예를 들면 AddShoesList 버튼
button.jsx
import { getList } from '../services/axios_list';
//상품추가 버튼
export function AddShoesList({shoes, setShoes}){ //객체 구조 분해 할당 사용 ({}) 활용
//서버에서 데이터 가지고오기 - axios 라이브러리 사용 JQuery 같은거
const fetchShoes = async () => {
try {
const data = await getList();
// 기존 shoes와 서버에서 가져온 데이터를 합침
const updatedShoes = [...shoes, ...data];
setShoes(updatedShoes);
} catch (error) {
console.error("상품 데이터를 불러오는 중 오류 발생:", error);
}
};
//services에 구현하자
return(
<button onClick={fetchShoes}>추가상품 버튼</button>
)
}
getList 같은 경우는 axios로 값을 들고왔는데 이것도 한번 알아보자
axios_list
// 서버데이터 - 리스트
import api from "./axios_setting.js";
export const getList = async ()=>{
try {
const response = await api.get('/shop/data2.json');
return response.data;
} catch (error) {
console.error("Error fetching user:",error);
throw error;
}
}
간단하다
그럼 axios 공통세팅도 알아볼까
axios_user.js
import axios from "axios";
const api = axios.create({
baseURL: "https://codingapple1.github.io", //기본url
// timeout: 5000, //시간제한
// headers: {
// "Content-Type":"application.json"
// },
});
// 요청 인터셉터(토큰추가)
// api.interceptors.request.use(
// (config)=>{
// const token = localStorage.getItem("token"); //토큰가져오기
// if(token){
// config.headers.Authorization = 'Bearer ${token}';
// }
// return config;
// },
// (error)=>Promise.reject(error)
// );
//응답 인터셉터(에러처리)
api.interceptors.response.use(
(response)=>response,
(error) => {
console.error("API Error:",error);
return Promise.reject(error);
}
);
export default api;
여기서 이것저것 환경설정 해주면 되겠다.
나중에 마이페이지 에서 axios + react-query 로 실시간 데이터 불러오는것도 정리할 예정
props : 부모 -> 자식 컴포넌트로 데이터 전달
Context api : 간단한 전역 상태 관리
Redux : 복잡한 전역 상태 관리