


const fetchData = async () => {
try {
setError(null);
setData(null);
setLoading(true);
const response = await axios.get(URL, {
params: {
serviceKey: serviceKey,
currentPage: 1,
perPage: 4,
},
});
// 응답 데이터가 유효한지 확인합니다
if (
response.data &&
response.data.body &&
Array.isArray(response.data.body)
) {
setData(response.data);
} else {
throw new Error("Invalid API response structure");
}
} catch (e) {
if (e.response) {
// 서버가 2xx 외의 상태로 응답한 경우
setError(`Server Error: ${e.response.status}`);
} else if (e.request) {
// 요청이 이루어졌지만 응답이 없는 경우 (CORS 문제일 수 있음)
setError("Network Error: No response received");
} else {
// 요청 설정 중에 문제가 발생한 경우
setError(`Error: ${e.message}`);
}
}
setLoading(false);
};
CORS 문제는 일반적으로 네트워크 오류나 요청 차단으로 이어지며, 이는 콘솔에서 다음과 같은 다른 에러 메시지로 나타납니다:
- "Access to fetch at '...' from origin '...' has been blocked by CORS policy."
- "No 'Access-Control-Allow-Origin' header is present on the requested resource."
- 하지만, 내가 만난 에러는 API 호출이 실패하거나 빈 데이터를 반환하는 경우(=요청 설정 중에 문제가 발생한 경우)일 가능성이 높았다.
- 따라서, 위와 같이 에러를 3가지로 구분하고 대응하였다.
- 서버의 문제일 경우
- 네트워크 문제일 경우 = CORS 문제 등
- 요청 설정 중에 문제일 경우 = API 호출이 실패하거나 빈 데이터를 반환하는 경우 등
- 결과
- 웹 화면에서 블랙 아웃 창은 발생하지는 않았지만, 새로 고침할 때마다 [ Error: ~~~ ] 로 시작하는 Text를 만났다.
- 즉, 요청 설정 중으로 인한 문제였던 것
무엇이 고민인지 생각해봤다.
fetch를 할 때, 동일한 결과를 아래와 같이 한 번에 한 번만 인출하는 것이 아니라 4번이나 인출하는 문제가 이전부터 있었다는 것을 알고 있었다.

문제는 App.js 파일이 아닌 index.js에 있는 Strict Mode가 문제였다. 따라서, index.js에 있는 Strict Mode를 없애주었다.
// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
⇒ Strict Mode
⇒ 결과


사실, 에러가 있을 때 제외하면 저번에 나왔던 결과 화면과 동일하다.
에러…를 해결한 것에 의의를 둔다.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
import axios from "axios";
import { useState, useEffect } from "react";
const URL =
"http://apis.data.go.kr/6430000/cbRecreationalForestInfoService/getRecreationalForestInfo?serviceKey=";
const serviceKey = process.env.REACT_APP_API_KEY; // 환경 변수에서 API 키를 가져옵니다
function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchData = async () => {
try {
setError(null);
setData(null);
setLoading(true);
const response = await axios.get(URL, {
params: {
serviceKey: serviceKey,
currentPage: 1,
perPage: 4,
},
});
// 응답 데이터가 유효한지 확인합니다
if (
response.data &&
response.data.body &&
Array.isArray(response.data.body)
) {
setData(response.data);
} else {
throw new Error("Invalid API response structure");
}
} catch (e) {
if (e.response) {
// 서버가 2xx 외의 상태로 응답한 경우
setError(`Server Error: ${e.response.status}`);
} else if (e.request) {
// 요청이 이루어졌지만 응답이 없는 경우 (CORS 문제일 수 있음)
setError("Network Error: No response received");
} else {
// 요청 설정 중에 문제가 발생한 경우
setError(`Error: ${e.message}`);
}
}
setLoading(false);
};
useEffect(() => {
fetchData();
}, []);
// console.log("Service Key:", serviceKey); // 콘솔에 서비스 키를 출력합니다
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!data) return null;
console.log(data);
return (
<div className="App">
<p>body 길이 : {data.body.length}</p>
<p>header currentPage : {data.header.currentPage}</p>
<p>휴양림명 : {data.body[0].NM}</p>
<p>위치 : {data.body[0].LC}</p>
<p>면적 : {data.body[0].AR}</p>
</div>
);
}
export default App;