根据货币选择获取货币汇率

时间:2021-02-06 04:32:10

标签: reactjs react-hooks

当我们在文本框中输入一些值并在 fromCurrency 下拉字段中输入货币并在 toCurrency 下拉字段中选择适当的货币时,我们如何在 toCurrency 中显示基于那个选择?

https://codesandbox.io/s/rough-http-jc35u?file=/src/App.js

import React, { useState, useEffect } from "react";
import "./styles.css";
const axios = require("axios");
function App() {
  const [sourceCurrency, setSourceCurrency] = useState("");
  const [targetCurrency, setTargetCurrency] = useState("");
  const [ratesList, setRatesList] = useState([]);
  const [selectFromCurrency, setFromSourceCurrency] = useState("");
  const [selectToCurrency, setSelectToCurrency] = useState("");

  const getSourceCurrency = (source) => {
    setSourceCurrency(source);
  };

  const getTargetCurrency = (target) => {
    setTargetCurrency(target);
  };

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data = await axios.get("https://api.exchangeratesapi.io/latest");
        setRatesList(data);
        console.log(data);
      } catch (e) {
        console.log(e);
      }
    };
    fetchData();
  }, []);

  const selectSourceCurrency = (sourceCurr) => {
    setFromSourceCurrency(sourceCurr);
  };

  const selectTargetCurrency = (targetCurr) => {
    setSelectToCurrency(targetCurr);
  };

  const convertRate = () => {
    const rateCalc = sourceCurrency * targetCurrency;
    console.log("print rate: " + rateCalc);
    // how can we the rates list here and based on the selection ?
    
  };

  return (
    <div className="App">
      <div className="globalCurrencyConverter">
        <h2>Currency Converter</h2>
        <div className="container box">
          <label>
            <input
              name="sourceCurrency"
              type="text"
              placeholder="fromCurrency"
              onChange={(event) => getSourceCurrency(event.target.value)}
            />
            <select
              className="fromCurrency"
              defaultValue={"DEFAULT"}
              onChange={(event) => selectSourceCurrency(event.target.value)}
            >
              <option>USD</option>
              <option value="DEFAULT">AUD</option>
              <option>NZD</option>
              <option>INR</option>
              <option>UAE Dirham</option>
            </select>
          </label>
          <label>
            <input
              name="targetCurrency"
              type="text"
              placeholder="toCurrency"
              onChange={(event) => getTargetCurrency(event.target.value)}
            />
            <select
              className="toCurrency"
              onChange={(event) => selectTargetCurrency(event.target.value)}
            >
              <option>USD</option>
              <option>AUD</option>
              <option>NZD</option>
              <option>INR</option>
              <option>UAE Dirham</option>
            </select>
          </label>
          <div className="recordBtn">
            <button name="convert" onClick={(event) => convertRate()}>
              Convert
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

2 个答案:

答案 0 :(得分:3)

我假设您可以自己处理这些带有货币的选定字段的数量,而是向您展示如何解决实际的转换问题。因此,我们将保留这些选择选项硬编码在您的代码中。例如(美元、新西兰元、澳元等)

所以我们实际上甚至不需要在这个测试中使用 useEffect,因为我们只是简单地对货币进行了硬编码。就我个人而言,我喜欢用尽可能少的重新渲染来解决我的 React 问题。所以我解决这个特定问题的方法是创建对所有 4 个字段的引用。它将允许我们随时访问它们的值。查看useRef()

然后,当有人输入所有信息并单击“转换”按钮时,我会调用您的 API 并将所选货币作为基础货币传递给它。像这样

https://api.exchangeratesapi.io/latest?base=USD

一旦 axios 获取其上的数据,它只是一些基本匹配和将正确值分配给“To Currency”字段的问题。所以这里有一个工作示例和一个 Sandbox:

import React, { useState, useEffect, useRef } from "react";
import "./styles.css";
const axios = require("axios");
function App() {
  const from_select = useRef(),
    to_select = useRef(),
    from_input = useRef(),
    to_input = useRef();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data = await axios.get("https://api.exchangeratesapi.io/latest");
        //setRatesList(data);
        console.log(data);
      } catch (e) {
        console.log(e);
      }
    };
    fetchData();
  }, []);

  const convertRate = () => {
    const from_cur = from_select.current.value;
    const to_cur = to_select.current.value;
    const from_amount = from_input.current.value;
    console.log(from_cur);
    axios
      .get("https://api.exchangeratesapi.io/latest?base=" + from_cur)
      .then((result) => {
        const rate = result.data.rates[to_cur];
        const converted_amount = rate * from_amount;
        to_input.current.value = converted_amount;
      });
  };

  return (
    <div className="App">
      <div className="globalCurrencyConverter">
        <h2>Currency Converter</h2>
        <div className="container box">
          <label>
            <input
              ref={from_input}
              name="sourceCurrency"
              type="text"
              placeholder="fromCurrency"
            />
            <select
              ref={from_select}
              className="fromCurrency"
              defaultValue={"USD"}
            >
              <option value="USD">USD</option>
              <option value="AUD">AUD</option>
              <option value="NZD">NZD</option>
            </select>
          </label>
          {" -> "}
          <label>
            <input
              ref={to_input}
              name="targetCurrency"
              type="text"
              placeholder="toCurrency"
            />

            <select ref={to_select} className="toCurrency" defaultValue="AUD">
              <option value="USD">USD</option>
              <option value="AUD">AUD</option>
              <option value="NZD">NZD</option>
              <option value="RUB">RUB</option>
              <option value="EUR">EUR</option>
            </select>
          </label>
          <div className="recordBtn">
            <button name="convert" onClick={convertRate}>
              Convert
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

答案 1 :(得分:1)

您的 ratesList 将是从 data.data.rates 中提取的对象,其国家键和费率值在初始 useEffect 设置为:

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data = await axios.get("https://api.exchangeratesapi.io/latest");
        setRatesList(data.data.rates);
      } catch (e) {
        console.log(e);
      }
    };
    fetchData();
  }, []);

您的 convertRate 首先验证 sourceCurrency 是否为数字且是否存在 ratesList。要计算转化率,您需要将金额值乘以比率 (toCurrency/FromCurrency):

  const convertRate = () => {
    if (isNaN(sourceCurrency) || !ratesList) return;

    setTargetCurrency(
      (ratesList[selectToCurrency] / ratesList[selectFromCurrency]) *
        sourceCurrency
    );
  };

设置货币的初始值:

  const [selectFromCurrency, setFromSourceCurrency] = useState("USD");
  const [selectToCurrency, setSelectToCurrency] = useState("NZD");

并删除选择和输入值的默认值。而是传递状态值以获得受控输入,例如:

  <select
    className="fromCurrency"
    value={selectFromCurrency}
    onChange={(event) => selectSourceCurrency(event.target.value)}
  >
    <option>USD</option>
    <option>AUD</option>
    <option>NZD</option>
    <option>INR</option>
    <option>PLN</option>
  </select>

对于您的 toCurrency 输入,将其设为禁用字段,因为您无需用户在其上键入值:

<input
  name="targetCurrency"
  value={targetCurrency}
  disabled
  type="text"
  placeholder="toCurrency"
/>

工作演示:

conversion-rate

注意:阿联酋迪拉姆与 API 响应不匹配,因此更改为 PLN