데이터 Fetching에서 발생할 수 있는 두 가지 주요 에러와 효과적인 관리법
데이터를 Fetching할 때 주로 발생하는 에러는 두 가지로 나뉜다.
- 요청 시도 자체가 실패한 경우:
잘못된 URL, 네트워크 충돌 등으로 인해 요청이 이루어지지 않는 경우이다. - 백엔드에서 에러가 발생한 경우:
요청은 정상적으로 전달되었지만, 서버 내부에서 문제가 발생하여 에러가 반환되는 경우이다.
1. Fetching을 위한 기본 코드 구조
React의 useEffect 안에서 데이터를 Fetching하는 기본적인 코드 구조는 아래와 같다:
import React, { useEffect, useState } from 'react';
function App() {
const [availablePlaces, setAvailablePlaces] = useState([]); // 데이터 상태
const [isLoading, setIsLoading] = useState(false); // 로딩 상태
const [error, setError] = useState(null); // 에러 상태
useEffect(() => {
async function fetchPlaces() {
setIsLoading(true);
try {
const response = await fetch('http://localhost:3000/places'); // API 호출
const resData = await response.json();
if (!response.ok) {
// 백엔드 에러 처리
throw new Error(resData.message || 'Could not fetch places.');
}
setAvailablePlaces(resData.places); // 상태 업데이트
} catch (error) {
setError({ message: error.message || 'Failed to fetch places' }); // 에러 처리
}
setIsLoading(false); // 로딩 종료
}
fetchPlaces();
}, []);
return (
<div>
{isLoading && <p>로딩 중...</p>}
{error && <p>{error.message}</p>}
{!isLoading && !error && (
<ul>
{availablePlaces.map((place, index) => (
<li key={index}>{place.name}</li>
))}
</ul>
)}
</div>
);
}
export default App;
2. 주요 포인트
- useEffect에서 무한 루프 방지:
데이터 Fetching은 useEffect 안에 넣어 한 번만 실행되도록 한다. - HTTP 응답 상태 코드 확인:
response.ok를 통해 상태 코드를 확인한다.- 성공: 200, 300대 코드
- 실패: 400, 500대 코드
- 로딩 및 에러 관리:
- isLoading 상태로 로딩 중임을 사용자에게 알린다.
- error 상태로 발생한 에러를 화면에 표시한다.
3. 중복된 Fetching 로직을 Hook으로 분리하기
중복되는 Fetching 로직은 별도의 Hook으로 만들어 관리할 수 있다. 아래는 Fetching을 위한 커스텀 Hook의 예시이다:
Fetching Hook 예시
export async function fetchUserPlaces() {
const response = await fetch('http://localhost:3000/user-places');
const resData = await response.json();
if (!response.ok) {
throw new Error(resData.message || 'Could not fetch user places.');
}
return resData.places; // 데이터 반환
}
Hook 활용 코드
useEffect(() => {
async function fetchPlaces() {
setIsLoading(true);
try {
const places = await fetchUserPlaces(); // Fetching Hook 호출
setAvailablePlaces(places);
} catch (error) {
setError({ message: error.message || 'Failed to fetch user places' });
}
setIsLoading(false);
}
fetchPlaces();
}, []);
4. 데이터 업데이트를 위한 Hook 예시
데이터 업데이트는 Fetching과 다르게 HTTP 메서드와 요청 본문(body)에 주의해야 한다. 아래는 업데이트를 처리하는 Hook의 예시이다:
export async function updateUserPlaces(places) {
const response = await fetch('http://localhost:3000/user-places', {
method: 'PUT',
body: JSON.stringify({ places }), // 객체 형태로 전달
headers: {
'Content-Type': 'application/json',
},
});
const resData = await response.json();
if (!response.ok) {
throw new Error(resData.message || 'Could not update user places.');
}
return resData.message; // 성공 메시지 반환
}
중요 포인트
- 데이터 형태 확인:
body에 전달하는 데이터의 형태는 백엔드에서 요구하는 구조를 따라야 한다. 예를 들어, places: places 형식으로 객체를 감싸지 않으면 에러가 발생한다.
5. 에러와 데이터 형태에 대한 주의사항
- GET/DELETE 요청:
일반적으로 데이터 형태를 크게 신경 쓰지 않아도 된다. - POST/PUT 요청:
데이터를 백엔드에서 요구하는 구조로 정확히 전달해야 한다. 특히, 업데이트 시 전달되는 데이터가 배열인지 객체인지 확인하여 문제를 방지한다.
6. 마무리
데이터 Fetching은 에러 처리, 로딩 상태 관리, 그리고 데이터의 형태를 정확히 이해하는 것이 핵심이다. 중복되는 로직은 Hook으로 분리하여 코드의 재사용성을 높이고, 각 요청의 목적(GET, POST, DELETE)에 맞는 적절한 구조로 작성하는 습관을 들이는 것이 중요하다. 이러한 구조를 익히면 보다 효율적으로 데이터 요청 및 처리를 구현할 수 있다.
'Frontend Study' 카테고리의 다른 글
React # 11 _ React에서 Custom Hook을 활용한 데이터 Fetching과 최적화 (1) | 2025.01.02 |
---|---|
React에서 자주 쓰이는 용어 정리 (영어/한국어) (0) | 2025.01.02 |
React # _ HTTP 요청 보내기 (1) | 2025.01.01 |
React #8 _ useState 마무리 정리 (1) | 2024.12.31 |
React #7 _ Key의 중요성 (0) | 2024.12.31 |