ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ์›ํ‹ฐ๋“œ ํ”„๋ฆฌ์˜จ๋ณด๋”ฉ ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”์Šค 1์ฃผ์ฐจ ํšŒ๊ณ  (2)
    ETC 2022. 2. 19. 15:46

    ์ฒซ ๋ฒˆ์งธ ๊ณผ์ œ๋Š” ๊ฐ„๋‹จํ•œ ํ™˜์œจ ๊ณ„์‚ฐ๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ œ์˜€๋‹ค.

    ์šฐ๋ฆฌ ํŒ€์€ ๋„ค ๋ช…์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ณ  ์ด๋ฒˆ ๊ณผ์ œ๋Š” ๋‘ ๋ช…์”ฉ ๋‚˜๋‰˜์–ด ํ•˜๋‚˜์˜ ๊ณ„์‚ฐ๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ œ์˜€๋‹ค. ๋‚ด๊ฐ€ ๋งก์€ ๋ถ€๋ถ„์€ ์ˆ˜์ทจ ๊ตญ๊ฐ€๋ฅผ ์„ ํƒํ•˜๊ณ  ์†ก๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด ๋ฒ„ํŠผ ํ•˜๋‹จ์— ์ˆ˜์ทจ๊ธˆ์•ก์ด ์ˆ˜์ทจ๊ตญ๊ฐ€์— ๋งž๋Š” ํ™˜์œจ๋กœ ๋ณ€ํ™˜๋˜์–ด ์ถœ๋ ฅ๋˜๋Š” ๊ณ„์‚ฐ๊ธฐ์˜€๋‹ค.

     

    ์ง€๊ธˆ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ฐธ ์—‰์„ฑํ•˜๋‹ค. ๊ฐ™์ด ํ”„๋ฆฌ์˜จ๋ณด๋”ฉ ์ฝ”์Šค๋ฅผ ์ฐธ์—ฌํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋ณด๋ฉด ์ด๋Ÿฐ์ €๋Ÿฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋‹ค๋ฃฐ ์ค„ ์•„๋Š” ๋ถ„๋“ค์ด ๋งŽ์ด ๊ณ„์‹ ๋ฐ ๋‚˜๋Š” ์–ด๋–ป๊ฒŒ ํ•ฉ๊ฒฉ์„ ํ•ด์„œ ๋ฐฐ์šฐ๊ณ  ์žˆ๋‚˜ ์‹ถ์„ ์ •๋„๋‹ค. ๋‚ด๊ฐ€ ๋ฌธ ๋‹ซ๊ณ  ๋“ค์–ด์˜จ ๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ๋‹ค.

     

    1. API ํ˜ธ์ถœ

    ํ™˜์œจ ์ •๋ณด๋ฅผ ๋ฐ›์•„ ์˜ค๊ธฐ ์œ„ํ•ด API๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ณ„์‚ฐ๊ธฐ๊ฐ€ ๋‘ ๊ฐ€์ง€์ธ๋ฐ, ๊ฐ™์€ ํ™˜์œจ API ์ •๋ณด๋ฅผ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์— redux toolkit์„ ์‚ฌ์šฉํ•ด ํ™˜์œจ ์ •๋ณด๋Š” ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ–ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ ์šฐ๋ฆฌ ํŒ€ ์ข…์› ๋‹˜๊ป˜์„œ ์ž‘์„ฑํ•˜์…จ๋‹ค.

    // store/index.js
    
    import { configureStore, createSlice } from "@reduxjs/toolkit";
    
    const exchangeRateSlice = createSlice({
      name: "currency",
      initialState: { exchangeRate: "" },
      reducers: {
        getExchangeRate(state, action) {
          state.exchangeRate = action.payload;
        },
      },
    });
    
    const store = configureStore({
      reducer: {
        rate: exchangeRateSlice.reducer,
      },
    });
    
    export const exchangeRateActions = exchangeRateSlice.actions;
    
    export default store;

    ๊ทธ๋ฆฌ๊ณ  App.js์—์„œ fetch๋ฅผ ์ด์šฉํ•ด json ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ํ™˜์œจ ์ •๋ณด๋ฅผ exchangeRate์— ์ €์žฅํ•œ๋‹ค.

    // App.js
    
    import { useEffect } from "react";
    import { useDispatch } from "react-redux";
    import { exchangeRateActions } from "./store";
    
    function App() {
      const dispatch = useDispatch();
    
      const getCurrency = async () => {
        const json = await (
          await fetch(
            `http://api.currencylayer.com/live?access_key=${apiKey}&format=1`
          )
        ).json();
        dispatch(exchangeRateActions.getExchangeRate(json.quotes));
      };
    
      useEffect(() => {
        getCurrency();
      }, [dispatch]);
    
      return (
        // ์ƒ๋žต
      );
    }
    
    export default App;

     

    2. ํ™˜์œจ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

    select ๋ฐ•์Šค๋กœ ๊ตญ๊ฐ€๋ฅผ ์„ ํƒํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹นํ•˜๋Š” ๊ตญ๊ฐ€์˜ ํ™˜์œจ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค.

    <select className={styles.textBox} onChange={handleChangeCountry}>
        <option value="KRW" select="true">ํ•œ๊ตญ(KRW)</option>
        <option value="JPY">์ผ๋ณธ(JPY)</option>
        <option value="PHP">ํ•„๋ฆฌํ•€(PHP)</option>
     </select>
    const [nation, setNation] = useState("KRW");
    
    const handleChangeCountry = (event) => {
        setNation(event.target.value);
      };

    onChange ์ด๋ฒคํŠธ์— handleChangeCountry ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•ด ์„ ํƒ ํ•ญ๋ชฉ์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค nation์„ ๋ณ€๊ฒฝํ•ด ์ค€๋‹ค.

      const exchangeRate = useSelector((s) => s.rate.exchangeRate);
      const saveRate = exchangeRate["USD" + nation];

    ๊ทธ๋ฆฌ๊ณ  useSelector๋กœ ํ™˜์œจ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ ๋‹ค์Œ, saveRate์— ํ˜„์žฌ ์„ ํƒํ•œ ๊ตญ๊ฐ€์˜ ํ™˜์œจ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

    API์˜ ๊ฐ’์ด USDKRW์ฒ˜๋Ÿผ USD + ๊ตญ๊ฐ€ ํ˜•์‹์œผ๋กœ ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์ด ํ™˜์œจ ๊ฐ’์„ ๋ฐ›์•„์˜จ๋‹ค.

    <p>
      ํ™˜์œจ:{" "}
      {saveRate?.toLocaleString(undefined, {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
      })}{" "}
      {nation}/USD
    </p>

    ๊ทธ๋ฆฌ๊ณ  ํ™”๋ฉด์—๋Š” saveRate์™€ nation์„ ์ด์šฉํ•ด 1,193.88 KRW/USD์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ™˜์œจ์„ ์ถœ๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

    toLocaleString()์€ ์ˆซ์ž์— 3์ž๋ฆฌ๋งˆ๋‹ค ์ฝค๋งˆ๋ฅผ ์ฐ์–ด ์ฃผ๋Š” ํ•จ์ˆ˜์ธ๋ฐ, ์†Œ์ˆ˜์  ๋‘ ์ž๋ฆฌ๊นŒ์ง€ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์˜ต์…˜์„ ์คฌ๋‹ค.

     

    ๊ณผ์ œ ๋ฆฌ๋ทฐ ์‹œ๊ฐ„์— ์•Œ๊ณ  ์•„์‰ฌ์› ๋˜ ์ ์€, ์†ก๊ธˆ์•ก Input์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’์ด ์˜ค๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ๋Š” ํ•ญ๋ชฉ์ด ์žˆ์—ˆ๋Š”๋ฐ type="number"๋กœ ์ œํ•œํ•ด ์ˆซ์ž ๊ฐ’๋งŒ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. ์ด ๋ฐฉ์‹์ด ์•„๋‹Œ type์„ ๊ฒ€์ฆํ•˜๊ณ  number๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์†ก๊ธˆ์•ก์ด ๋ฐ”๋ฅด์ง€ ์•Š๋‹ค๋Š” ๋ฌธ๊ตฌ๋ฅผ ๋„์›Œ์•ผ ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ–ˆ๋‹ค.

    {Number(sendMoney) < 0 ||
      Number(sendMoney) > 10000 ||
      isNaN(Number(sendMoney)) ? (
      ์†ก๊ธˆ์•ก์ด ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค
      : (
        ์ˆ˜์ทจ๊ธˆ์•ก์€ ์–ผ๋งˆ์ž…๋‹ˆ๋‹ค
      )}

    ์ฒซ ๋ฒˆ์งธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งˆ์น˜๋ฉฐ

    ์›ํ‹ฐ๋“œ ํ”„๋ฆฌ์˜จ๋ณด๋”ฉ ์ฝ”์Šค์—์„œ ํ•œ ์ฒซ ํ˜‘์—…!์ด๋ผ๋Š” ๊ฒƒ์— ์˜๋ฏธ๋ฅผ ๋‘๊ณ  ์‹ถ๋‹ค. ๋ถ„๋ช… ์„œํˆฐ ๋ถ€๋ถ„์ด ํ›จ์”ฌ ๋งŽ๊ณ , ๋‚˜์ค‘์— ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๋ณด๋ฉด ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ์—ฌ์‹คํžˆ ๋ณด์ผ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ ๋‚ด๊ฐ€ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐœํŒ์ด ๋  ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ง  ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ๊ณ , ์–ด๋–ค ๋ถ€๋ถ„์ด ๋ชจ์ž๋ž€์ง€ ๊ทธ๋ž˜์„œ ์–ด๋–ค ๋ถ€๋ถ„์„ ๋ณด๊ฐ•ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์กธ์—…์— ์น˜์—ฌ ์šธ๋ฉฐ ๊ฒจ์ž ๋จน๊ธฐ๋กœ ์ฝ”๋”ฉํ–ˆ์„ ๋•Œ์™€ ๋‹ค๋ฅด๊ฒŒ ๊ฐœ๋ฐœ์ž๋ผ๋Š” ๊ธธ๋กœ ๋“ค์–ด์„œ๊ณ  ์‹ถ๋‹ค๋Š” ๋งˆ์Œ์ด ์กฐ๊ธˆ ๋” ๊ตณ์–ด์ง„ ๊ฒƒ ๊ฐ™๋‹ค. ์•ž์œผ๋กœ๋„ ๋”๋” ์—ด์‹ฌํžˆ ํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค~

     

     

     

    GitHub - ttaerrim/wanted_pre_onboarding_01: <ํ™˜์œจ ๊ณ„์‚ฐ๊ธฐ>

    <ํ™˜์œจ ๊ณ„์‚ฐ๊ธฐ>. Contribute to ttaerrim/wanted_pre_onboarding_01 development by creating an account on GitHub.

    github.com

     

    ๋Œ“๊ธ€

Designed by Tistory.