React
환전(환율) 계산기 만들기 ② FE
code10
2023. 3. 14. 14:48
FE : React , yarn
BE: Express, npm
FE 최종 코드
//App.js
import React, { useCallback, useEffect, useState } from "react";
import instance from "./API/instance";
import "./App.css";
import CurrencyBox from "./components/CurrencyBox";
import Spinner from "./components/Spinner";
function App() {
const [data, setData] = useState([]);
const [list, setList] = useState([]);
const [date, setDate] = useState("");
const [rate, setRate] = useState();
const [money, setMoney] = useState(1);
const [inputMoney, setInputMoney] = useState(true);
const [currencyCodeFrom, setCurrencyCodeFrom] = useState("USD"); //from
const [currencyCodeTo, setCurrencyCodeTo] = useState("KRW"); //to
const [nationFrom, setNationFrom] = useState("미국 달러"); //from
const [nationTo, setNationTo] = useState("대한민국 원"); //to
let amount1, amount2;
if (inputMoney) {
amount1 = money;
amount2 = money * rate;
} else {
amount2 = money;
amount1 = money / rate;
}
const onChange1 = (e) => {
const str = e.target.value;
if (isNaN(str)) {
setMoney(0);
} else {
const regex = /[^0-9.]+/g;
const money = str.replace(regex, "");
setMoney(money);
setInputMoney(true);
}
};
const onChange2 = (e) => {
const str = e.target.value;
if (isNaN(str)) {
setMoney(0);
} else {
const regex = /[^0-9.]+/g;
const money = str.replace(regex, "");
setMoney(money);
setInputMoney(false);
}
};
const rateDB = useCallback(
async () => {
try {
const response = await instance.post(`/api?from=${currencyCodeFrom}&to=${currencyCodeTo}`);
setRate(response.data.exchangeRate);
setDate(response.data.date);
} catch (error) {
console.log(error);
}
}, [currencyCodeFrom, currencyCodeTo]);
const currencynNationDB = async () => {
try {
const response = await instance.get(`/currencynationlist`);
const listData = Object.values(response.data);
setData(listData);
const nations = listData
.map((v) => `${v.nation} ${v.currencyName}`)
.sort();
setList(nations);
} catch (error) {
console.log(error);
}
};
const opt = list.map((v) => (
<option value={v} key={v}>
{v}
</option>
));
const handleSelected1 = (e) => {
setNationFrom(e.target.value);
for (let value of data) {
const country = e.target.value.split(" ")[0];
if (value.nation === country) {
setCurrencyCodeFrom(value.currencyCode);
}
}
};
const handleSelected2 = (e) => {
setNationTo(e.target.value);
for (let value of data) {
const country = e.target.value.split(" ")[0];
if (value.nation === country) {
setCurrencyCodeTo(value.currencyCode);
}
}
};
useEffect(() => {
currencynNationDB();
rateDB();
}, [rateDB]);
return (
<>
<div className="wrap">
<header>
<h1>환전 계산기</h1>
{!rate? <Spinner/>: null}
<p>{date}</p>
</header>
<div className="currency-box">
<CurrencyBox
name="input1"
opt={opt}
selectedNation={nationFrom}
handleSelected={handleSelected1}
money={amount1}
onChange={onChange1}
/>
<CurrencyBox
name="input2"
opt={opt}
selectedNation={nationTo}
handleSelected={handleSelected2}
money={amount2}
onChange={onChange2}
/>
</div>
</div>
<p className="ref">
환율 기준 참고 API:{" "}
<a
href="https://exchangerate.host/#/#docs"
style={{ color: "gray" }}
target="_blank"
rel="noreferrer"
>
https://exchangerate.host/#/#docs
</a>
</p>
</>
);
}
export default App;
=> useEffect에서 warning이 있었는데, 고치려고 하면 rateDB에서 warning(노란 줄)이 발생하고... useCallback으로 해결할 수 있었다.
//components/CurrencyBox.js
import React from "react";
function CurrencyBox(props) {
const { opt, selectedNation, handleSelected, money, onChange,} = props;
let amount
amount = money.toLocaleString('ko-KR', {maximumFractionDigits: 2});
return (
<div className="input-box">
<input type="text" min={0} onChange={onChange} value={amount} aria-label={selectedNation}/>
<select value={selectedNation} onChange={handleSelected}>
{opt}
</select>
</div>
);
}
export default CurrencyBox;
//components/Spinner.js
import React from "react";
function Spinner(props){
return(
<div style={{margin: "auto", color: "#6f6f6f", opacity: "70%"}}>
<h2>❤️로딩중❤️</h2>
</div>
)
}
export default Spinner;
=> 백엔드 코드 고치기 전에 rate 받아오는 게 너무 느려서 spinner를 만들었었다.
//API/instance.js
import axios from "axios"
const instance = axios.create({
baseURL: "http://localhost:8080",
timeout: 5000,
headers: {
"Access-Control-Allow-Origin": `http://localhost:8080`,
'Access-Control-Allow-Credentials': "true",
}
})
export default instance;
=> headers에 적용한 부분은 쿠키를 사용해 주고받는 게 없어서(? : 쿠키를 사용하면 FE, BE 둘 다 설정 필요하다는 글을 봤는데, 직접 확인해 보진 못함.) 불필요할지도 모르겠다. 백엔드에서 이미 해당 부분을 설정해놔서 그런지 headers 부분이 없어도 오류없이 잘 작동하는 것을 확인했다. prac이니 일단 기재해 놓음. timeout은 요청에 대한 시간 제한을 두는 건 좋으니까-!