일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 제네릭
- 어윈 사용법
- 생성자오버로드
- Java
- 한국건설관리시스템
- abstract
- EnhancedFor
- 환경설정
- NestedFor
- 인터페이스
- GRANT VIEW
- 대덕인재개발원
- exception
- 예외처리
- 정수형타입
- 사용자예외클래스생성
- cursor문
- 집합_SET
- 예외미루기
- 다형성
- 오라클
- 참조형변수
- 컬렉션 타입
- 객체 비교
- 컬렉션프레임워크
- oracle
- 자동차수리시스템
- 추상메서드
- 메소드오버로딩
- 자바
- Today
- Total
거니의 velog
(24) 리액트와 상품 API 서버 연동 3 본문
3. 목록 페이지와 목록 컴포넌트 처리
* 목록 페이지와 목록 컴포넌트 처리 역시 이전의 Todo 예제와 유사하다. useCustomMove를 이용하면 이동과 관련된 처리를 쉽게 처리할 수 있고 FetchingModal을 이용해서 서버와의 통신 과정에 보여주도록 처리한다.
* 우선 api/productsApi.js에는 서버에서 목록 데이터를 가져오기 위한 함수를 준비한다.
import axios from "axios";
import { API_SERVER_HOST } from "./todoApi";
const host = `${API_SERVER_HOST}/api/products`;
export const postAdd = async (product) => {
const header = { headers: { "Content-Type": "multipart/form-data" } };
// 경로 뒤 '/' 주의
const res = await axios.post(`${host}/`, product, header);
return res.data;
};
export const getList = async (pageParam) => {
const { page, size } = pageParam;
const res = await axios.get(`${host}/list`, {
params: { page: page, size: size },
});
return res.data;
};
(1) ListComponent 처리
* 실제 목록 화면 내용을 보여줄 ListComponent를 components/products/ 폴더에 추가한다.
import React, { useEffect, useState } from "react";
import { getList } from "../../api/productsApi";
import useCustomMove from "../../hooks/useCustomMove";
import FetchingModal from "../common/FetchingModal";
const initState = {
dtoList: [],
pageNumList: [],
pageRequestDTO: null,
prev: false,
next: false,
totoalCount: 0,
prevPage: 0,
nextPage: 0,
totalPage: 0,
current: 0,
};
const ListComponent = () => {
const { page, size, refresh, moveToList, moveToRead } = useCustomMove();
//serverData는 나중에 사용
const [serverData, setServerData] = useState(initState);
//for FetchingModal
const [fetching, setFetching] = useState(false);
useEffect(() => {
setFetching(true);
getList({ page, size }).then((data) => {
console.log(data);
setServerData(data);
setFetching(false);
});
}, [page, size, refresh]);
return (
<div className="border-2 border-blue-100 mt-10 mr-2 ml-2">
<h1>Products List Component</h1>
{fetching ? <FetchingModal /> : <></>}
</div>
);
};
export default ListComponent;
* pages/products 폴더의 ListPage에 ListComponent를 추가한다.
import React from "react";
import ListComponent from "../../components/products/ListComponent";
const ListPage = () => {
return (
<div className="p-4 w-full bg-white">
<div className="text-3xl font-extrabold">Products List Page</div>
<ListComponent />
</div>
);
};
export default ListPage;
[목록 데이터의 출력]
* ListComponent는 API 서버에서 가져온 목록 데이터는 이미지 파일의 이름이 포함되어 있으므로 이를 화면에 출력해 줄 때 서버의 경로를 이용해야 한다.
(...)
import { API_SERVER_HOST } from "../../api/todoApi";
const host = API_SERVER_HOST;
(...)
* 화면에 데이터를 출력하는 부분은 아래와 같이 작성한다. 목록 데이터의 출력 시에 useCustomMove를 통해 만든 moveToRead를 이용해서 상품 조회 페이지로 이동이 가능하도록 구성한다.
import React, { useEffect, useState } from "react";
import { getList } from "../../api/productsApi";
import useCustomMove from "../../hooks/useCustomMove";
import FetchingModal from "../common/FetchingModal";
import { API_SERVER_HOST } from "../../api/todoApi";
const host = API_SERVER_HOST;
const initState = {
dtoList: [],
pageNumList: [],
pageRequestDTO: null,
prev: false,
next: false,
totoalCount: 0,
prevPage: 0,
nextPage: 0,
totalPage: 0,
current: 0,
};
const ListComponent = () => {
const { page, size, refresh, moveToList, moveToRead } = useCustomMove();
//serverData는 나중에 사용
const [serverData, setServerData] = useState(initState);
//for FetchingModal
const [fetching, setFetching] = useState(false);
useEffect(() => {
setFetching(true);
getList({ page, size }).then((data) => {
console.log(data);
setServerData(data);
setFetching(false);
});
}, [page, size, refresh]);
return (
<div className="border-2 border-blue-100 mt-10 mr-2 ml-2">
{fetching ? <FetchingModal /> : <></>}
<div className="flex flex-wrap mx-auto p-6">
{serverData.dtoList.map((product) => (
<div
key={product.pno}
className="w-1/2 p-1 rounded shadow-md border-2"
onClick={() => moveToRead(product.pno)}
>
<div className="flex flex-col h-full">
<div className="font-extrabold text-2xl p-2 w-full ">
{product.pno}
</div>
<div className="text-1xl m-1 p-2 w-full flex flex-col">
<div className="w-full overflow-hidden ">
<img
alt="product"
className="m-auto rounded-md w-60"
src={`${host}/api/products/view/s_${product.uploadFileNames[0]}`}
/>
</div>
<div className="bottom-0 font-extrabold bg-white">
<div className="text-center p-1">이름: {product.pname}</div>
<div className="text-center p-1">가격: {product.price}</div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
);
};
export default ListComponent;
* 브라우저를 이용해서 상품목록을 확인한다. 아직 상품 조회에 대한 구현이 완성되지 않았으므로 상품을 클릭했을 때 에러 화면만을 보게 된다.
(2) 페이지 이동
* 페이지의 이동은 이미 useCustomMove()를 이용해서 moveToList()를 이용할 수 있고, 페이징 처리 역시 common 폴더에 PageComponent를 제작해 두었기 때문에 이를 활용하면 손쉽게 구현이 가능하다.
import React, { useEffect, useState } from "react";
import { getList } from "../../api/productsApi";
import useCustomMove from "../../hooks/useCustomMove";
import FetchingModal from "../common/FetchingModal";
import PageComponent from "../common/PageComponent";
import { API_SERVER_HOST } from "../../api/todoApi";
const host = API_SERVER_HOST;
const initState = {
(...)
};
const ListComponent = () => {
const { page, size, refresh, moveToList, moveToRead } = useCustomMove();
//serverData는 나중에 사용
const [serverData, setServerData] = useState(initState);
//for FetchingModal
const [fetching, setFetching] = useState(false);
useEffect(() => {
setFetching(true);
getList({ page, size }).then((data) => {
console.log(data);
setServerData(data);
setFetching(false);
});
}, [page, size, refresh]);
return (
<div className="border-2 border-blue-100 mt-10 mr-2 ml-2">
(...)
<PageComponent
serverData={serverData}
movePage={moveToList}
></PageComponent>
</div>
);
};
export default ListComponent;
* 화면의 아래 쪽에는 페이지 번호가 출력되는 것을 확인할 수 있다. 페이지 번호는 데이터의 수에 따라 이전/다음 이동이 가능해 진다. 마찬가지로 useCustomMove를 이용해서 moveToRead()를 이용하면 조회 화면으로 이동이 가능해 진다.
'SpringBoot_React 풀스택 프로젝트' 카테고리의 다른 글
(26) 리액트와 상품 API 서버 연동 5 (0) | 2024.03.05 |
---|---|
(25) 리액트와 상품 API 서버 연동 4 (0) | 2024.03.05 |
(23) 리액트와 상품 API 서버 연동 2 (1) | 2024.03.05 |
(22) 리액트와 상품 API 서버 연동 1 (0) | 2024.03.05 |
(21) 상품 API 서버 구성하기 6 (0) | 2024.03.04 |