이 글은 또 왜 쓰게 되었는가
명지대학교 검색 커뮤니티의 명대신문에서 데이터(신문 데이터)를 Fetching하는 로직을 짜다가 나온 문제이다.
API 데이터를 관리할 때, 여러 개의 카테고리 데이터 (Request Paramter로) 를 어떻게 관리할 것인가? 하는 문제를 마주하게 됐다.
이때 각각의 상태를 따로 관리하는 방식과 동적 키를 활용하는 방식을 학습했는데 헷갈릴만한 소지가 있다고 판단하여 글을 남긴다.
API 명세서 구조 (Request Param으로 카테고리 별 뉴스 기사 조회)
### **📌`GET /api/v1/news?category={}`**
- **Description:** RequestParam을 이용하여 특정 카테고리의 기사를 DB에서 가져옵니다.
- **HTTP Method:** **`GET`**
- **RequestParam :**
- **`REPORT(보도)`**
- **`SOCIETY(사회)`**
{
"status": "success",
"data": [
{
"title": "오늘의 주요 뉴스",
"summary": "오늘의 뉴스 내용을 요약합니다.",
"imageUrl": "https://example.com/image.jpg",
"link": "https://example.com/news/1"
},
{
"title": "경제 뉴스",
"summary": "경제 관련 뉴스를 제공합니다.",
"imageUrl": "https://example.com/image2.jpg",
"link": "https://example.com/news/2"
}
]
}
동적 키 없이 개별 상태를 관리하는 방식
Request Parameter, 즉 서버에 엔드포인트에 변수를 집어넣어서 각기 다른 데이터를 fetching 해야한다는 것을 고려해보자.
초보자인 내가 가장 먼저 떠올릴 수 있는 방식은 각 카테고리마다 별도의 상태(state)를 관리하는 것이었다.
아래처럼 News 카테고리별 상태를 두개 만들어서 변수에다가 어떻게보면 하드코딩하면 될듯하다.
Request Parameter에 그냥 Default Parameter 하듯
apiClinet.get('/news', {params : {category : 'REPORT' }}
import { useEffect, useState } from 'react';
import apiClient from '../api/apiClient';
const NewsComponent = () => {
const [reportNews, setReportNews] = useState([]);
const [societyNews, setSocietyNews] = useState([]);
useEffect(() => {
const fetchReportNews = async () => {
const response = await apiClient.get('/news', { params: { category: 'REPORT' } });
setReportNews(response.data.data);
};
const fetchSocietyNews = async () => {
const response = await apiClient.get('/news', { params: { category: 'SOCIETY' } });
setSocietyNews(response.data.data);
};
fetchReportNews();
fetchSocietyNews();
}, []);
return (
<div>
<h2>보도 뉴스</h2>
{reportNews.map((news, index) => (
<p key={index}>{news.title}</p>
))}
<h2>사회 뉴스</h2>
{societyNews.map((news, index) => (
<p key={index}>{news.title}</p>
))}
</div>
);
};
export default NewsComponent;
단점이 있긴있죠 이래 하면
❌ 코드 중복이 많다. 같은 API 호출 패턴을 여러 번 작성해야 한다.
❌ 카테고리가 추가될 때마다 useState와 useEffect를 추가해야 한다. (유지보수 어려움)
❌ REPORT, SOCIETY 등 특정 카테고리에 코드가 하드코딩되어 확장성이 떨어진다.
동적 키를 활용한 상태 관리 방식
이제 동적 키(Dynamic Key)를 활용하는 방식을 적용한다면 좀 더 나아지겠다.
이 방식에서는 하나의 상태(newsData)에서 모든 카테고리 데이터를 관리 ( Request Parameter로 인한 동적 Fetching 고려 가능)
setNewsData((prevData) => ({
...prevData,
[category]: response.data.data,
}));
이 부분이 아마 어려울수 있는데, [category] 를 배열로 생각하면 안됌
[category]에서 배열처럼 보이는 대괄호는 그냥 동적 키 문법이다.
동적 키 활용
import { useEffect, useState } from 'react';
import apiClient from '../api/apiClient';
const NewsComponent = () => {
const [newsData, setNewsData] = useState({ REPORT: [], SOCIETY: [] });
const fetchNewsInfo = async (category) => {
const response = await apiClient.get('/news', { params: { category } });
setNewsData((prevData) => ({
...prevData,
[category]: response.data.data, // 동적 키 활용
}));
};
useEffect(() => {
['REPORT', 'SOCIETY'].forEach((category) => fetchNewsInfo(category));
}, []);
return (
<div>
<h2>보도 뉴스</h2>
{newsData.REPORT.map((news, index) => (
<p key={index}>{news.title}</p>
))}
<h2>사회 뉴스</h2>
{newsData.SOCIETY.map((news, index) => (
<p key={index}>{news.title}</p>
))}
</div>
);
};
export default NewsComponent;
참고사항 (Request Paramet vs URL Path Parameter)
📍 Request Parameter (쿼리 스트링 ?key=value 방식)
• 여러 개의 필터를 전달할 때 사용
• 예: GET /news?category=REPORT&date=2024-03-16
• 여러 개의 데이터를 쉽게 조합할 수 있음
📍 URL Path Parameter (/:value 방식)
• 특정한 리소스를 식별할 때 사용
• 예: GET /news/REPORT
• 보통 리소스의 ID와 같은 고유한 값을 요청할 때 사용됨
'FrontEnd Develop > Project : Team Nova MJ Search' 카테고리의 다른 글
비동기 함수와 useEffect에서의 처리 방식 쉽게 이해하기 (0) | 2025.03.20 |
---|---|
LocalStorage와 SessionStorage를 활용한 로그인 전역 상태 유지 및 Fetching UI JANK, UX 개선 (0) | 2025.03.06 |
프로젝트에 Open API 적용하기 (0) | 2025.01.14 |
<React + Vue.js> 프로젝트 내 회원가입 기능 구현 가이드 (0) | 2025.01.12 |
React x Style <Global Style과 Routing의 조합> : 프로젝트 구조의 최적의 사용법 (0) | 2025.01.10 |