【问题标题】:Get currency rates based on currency selection根据货币选择获取货币汇率
【发布时间】:2021-02-06 04:32:10
【问题描述】:

当我们在文本框中输入一些值并在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;

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

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

    因此,我们实际上甚至不需要该 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;
    

    【讨论】:

    • 谢谢。如果我需要在选择 toCurrency 期间首先显示转换率 toCurrency 文本字段,我们应该创建如下:const selectTargetCurrency = () =&gt; { const from_cur = from_select.current.value; const to_cur = to_select.current.value; axios .get("https://api.exchangeratesapi.io/latest?base=" + from_cur) .then((result) =&gt; { const rate = result.data.rates[to_cur]; setTargetCurrency(rate); }); }
    • toCurrency 选择框更改时调用上述内容>> onChange={(event) => selectTargetCurrency(event.target.value)}
    • @soccerway 差不多。我更新了我的沙盒以反映所选货币的汇率:codesandbox.io/s/green-wood-4uzwx?file=/src/App.js
    • 太棒了,我已经接受并投票了。感谢您的回复
    【解决方案2】:

    您的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"
    />
    

    工作演示:

    注意:阿联酋迪拉姆在 API 响应中不匹配,因此针对 PLN 进行了更改

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 2016-04-27
      • 1970-01-01
      • 2018-03-18
      • 2021-01-30
      相关资源
      最近更新 更多