react에서 .env 파일을 사용하기 위해서는 react 프로젝트 최상위 루트에 dotenv 라이브러리를 설치해야합니다.
dotenv는 환경변수를 .env 파일에 저장시켜주며 process.env로 로드하며,
특히 .env 파일에는 사용자에게 공개되면 안되는 값들을 변수로 저장하여 사용합니다.
package.json파일과 같은 경로에 .env 로 새로운 파일을 생성해주고 react에서는 앞에 'REACT_APP_'을 붙여주어야 인식이 가능합니다.
저는 변수이름 'API_KEY'로 설정하였고 뒤에 API 신청 후 발급받은 인코딩 키를 적어주었습니다.
데이터, 로딩 상태, 에러 상태, 요청 URL, 불러올 인코딩 키 값을 저장할 변수들을 생성합니다.
요청 URL은 전역에서 사용되기위해 전역 변수로 선언해줍니다!!!
import { useEffect, useState } from "react";
const URL = "요청 URL";
export default function Main() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const key = process.env.REACT_APP_API_KEY;
return(
<div></div>
);
}
API를 받아오기위한 데이터 수신방식은 GET 방식이고 axios 모듈을 사용합니다.
파라미터는 개발자가 원하는 페이지의 목적에 바꾸어 수정하여 사용합니다.
저는 일단 첫 번째 데이터의 전체목록을 불러오겠습니다.
import axios from "axios";
import { useEffect, useState } from "react";
const URL = " 요청 URL ";
export default function Main() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const key = process.env.REACT_APP_API_KEY; // .env파일에 저장해둔 API 서비스 키
const fetchData = async () => {
try {
setError(null);
setData(null);
setLoading(true);
const response = await axios.get(URL, {
params: {
serviceKey: decodeURIComponent(key), // 인코딩 재발을 방지한 디코딩
dataNo: 1, // 요청할 파라미터
},
});
setData(response);
} catch (e) {
setError(e);
}
setLoading(false);
};
useEffect(() => {
fetchData();
}, []);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!data) return null;
return(
<div></div>
);
}
※ 우리가 받아온 공용 API는 인코딩되어져 있는 값이기 떄문에 위의 decodeURIComponent 함수를 사용하지 않는 다면 SERVICE KEY IS NOT REGISTERED ERROR 가 발생할 수 있다.
console.log로 response를 출력해보면 xml 형식의 데이터가 넘어오신것을 볼 수 있습니다.
실제 페이지에서 개발자모드( F12 )에 들어가보면 아래와 같이 정보를 받아온 것을 확인할 수 있습니다.
하지만, 우리가 원하는 것은 data안의 각각의 값 중 꽃이름, 꽃말 등의 필요한 정보만을 추출해야 하므로 JSON 파일로 바꿔주어 값에 접근해야합니다.
이를 위해, 저는 xml2js 모듈을 설치하여 사용하였습니다.
다음은 실제 xml2js를 적용한 코드입니다!
// XML 데이터를 JSON으로 변환
xml2js.parseString(response.data, (err, result) => {
if (err) {
throw err;
}
const jsonData = JSON.parse(result);
setData(jsonData);
});
제가 가져온 데이터는 여기서 문제가 발생하였습니다...
데이터의 형식이 json 형식과 맞지않다는것!!!
따라서, 일단 xml 파일을 문자열로 바꾸고 json파일 형식에 맞추어 앞뒤로 슬라이싱을 사용하였습니다.
xml2js.parseString(response.data, (err, result) => {
if (err) {
throw err;
}
const jsonData = JSON.stringify(result); // xml 파일을 문자열로 저장
var data1 = jsonData.slice(21); // 앞에서 21자 슬라이싱
var data2 = data1.slice(0, -3); // 뒤에서 3자 슬라이싱
const result_data = JSON.parse(data2); // JSON파일로 변환
console.log(result_data.result[0].flowNm); // 실제 데이터에 접근 후 출력
setData(result_data.result[0]);
});
개발자모드에서 콘솔을 확인해보니
실제로 원하는 데이터가 넘어온 것을 확인할 수 있었습니다!
그럼 마지막으로 전체코드입니다.
import axios from "axios";
import { useEffect, useState } from "react";
import xml2js from "react-native-xml2js";
const URL = " 요청 URL ";
export default function Main() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const key = process.env.REACT_APP_API_KEY;
const fetchData = async () => {
try {
setError(null);
setData(null);
setLoading(true);
const response = await axios.get(URL, {
params: {
serviceKey: decodeURIComponent(key),
dataNo: 1,
},
});
// XML 데이터를 JSON으로 변환
xml2js.parseString(response.data, (err, result) => {
if (err) {
throw err;
}
const jsonData = JSON.stringify(result);
var data1 = jsonData.slice(21);
var data2 = data1.slice(0, -3);
const result_data = JSON.parse(data2);
console.log(result_data.result[0].flowNm);
setData(result_data.result[0]);
});
} catch (e) {
setError(e);
}
setLoading(false);
};
useEffect(() => {
fetchData();
}, []);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!data) return null;
return (
<div>
<div>
<h1>{data.flowNm}</h1>
<p><strong>학명:</strong> {data.fSctNm}</p>
<p><strong>영문 이름:</strong> {data.fEngNm}</p>
<p><strong>꽃 언어:</strong> {data.flowLang}</p>
<p><strong>설명:</strong> {data.fContent}</p>
<p><strong>용도:</strong> {data.fUse}</p>
<p><strong>성장:</strong> {data.fGrow}</p>
<p><strong>품종:</strong> {data.fType}</p>
<img src={data.imgUrl1} alt="꽃 이미지 1" />
<img src={data.imgUrl2} alt="꽃 이미지 2" />
<img src={data.imgUrl3} alt="꽃 이미지 3" />
<p><strong>출처:</strong> {data.publishOrg}</p>
</div>
</div>
);
}