如何使用Fixer.io react和material-UI构建一个货币转换器

416 阅读7分钟

使用Fixer.io react和material-UI构建一个货币转换器

货币转换器是一个显示世界上不同货币所代表的等值的应用程序。本文将逐步指导读者用React构建一个货币转换应用程序,并使用Material UI对其组件进行造型。

本文的先决条件

  • 一个文本编辑器,例如VSCode。
  • 对HTML、CSS和JavaScript编程语言有良好的理解。
  • 一个工作中的Node.js安装。

创建React应用程序

前往项目文件夹,运行下面的命令,创建一个新的React应用程序。

npx create-react-app project-name

创建新的React应用程序后,打开文本编辑器,清除App.jsApp.css 中的默认代码,以准备将Material UI整合到你的应用程序中。要在浏览器中本地打开该应用程序,请运行。

npm start

开始使用Material UI

Material UI是一个基于组件的CSS框架,通过为项目的不同部分提供几个相关的组件,帮助开发者构建React应用程序。

MUI组件单独工作。它们是自我支持的,只会显示它们需要显示的样式。因此,它们不依赖于全世界的样式表,如normalize.css

你需要@material-ui/core ,它可以很容易地与npmyarn 一起安装。如果你希望使用图标,你也可以包括@material-ui/icons 包。

以下是将这些包作为依赖项安装在你的应用程序中的命令。

npm install @material-ui/core @material-ui/icons

现在,你可以在你的应用程序的package.json 文件中找到Material UI,如下图所示。

package-json

要在你的应用程序中使用任何Material UI组件,请前往MUI官方文档的组件页面。然后,你可以按照文档中的说明利用任何一个组件。

最理想的是参考每个组件的演示页面,看看它们应该如何被导入。下面是一个代码示例,它将向你展示在你的应用程序中使用MUI所需要的一切。

import * as React from 'react';
import ReactDOM from 'react-dom';
import Button from '@mui/material/Button';

function App() {
  return <Button variant="contained">Hello World</Button>;
}

ReactDOM.render(<App />, document.querySelector('#app'));

构建货币转换器

这个应用程序将有来自Material UI的 "美元图标",一个标题,两个inputs ,用于你正在比较的货币,以及两个select 组件,你将使用它们来选择货币。

这个应用程序将使用fixer.io API来获取最新的货币汇率。因此,如果你改变一种货币的数值,另一种设定货币的等值将自动显示。

要开始使用,请创建一个新文件,并将其命名为CurrencyInput.js 。创建一个CurrencyInput 函数并传入props 作为参数。然后,创建两个inputselect 元素。在inputselect 标记中分别传入props.amountprops.currency 作为值。

接下来,设置一个map 函数,该函数将在select 标记中遍历option 标记,我们将称之为currency ,并将其值设置为currency

接下来要做的是定义propTypes 。在React中,propTypes 是一种机制,确保组件使用正确的数据排序并传递正确的数据,组件使用正确类型的props ,接收组件获得正确类型的props 。要做到这一点,首先,在终端运行下面的命令。

yarn add prop-types

接下来,导入并调用本应用程序所需的propsTypesamount ,作为numbercurrency ,作为一个stringcurrencies ,作为一个阵列。最后,导出CurrentInput 函数。下面是该程序的代码。

import React from 'react'
import propTypes from "prop-types"

const CurrencyInput = (props) => {
    return (
        <div className="currency-input">
            <input type="text" value={props.amount} onChange={event => props.onAmountChange(event.target.value)}  />
            <select value={props.currency} onChange ={event => props.onCurrencyChange(event.target.value)}>
                {props.currencies.map((currency => (
                    <option value={currency}>{currency}</option>
                )))}
                </select>   
        </div>
    )
}

CurrencyInput.propTypes = {
    amount: propTypes.number.isRequired,
    currency: propTypes.string.isRequired,
    currencies: propTypes.array,
    onAmountChange: propTypes.func,
    onCurrencyChange: propTypes.func
}

export default CurrencyInput

为应用程序组件创建状态

前往App.js 文件,创建一个新的App 函数。接下来,使用钩子useState ,创建四个状态,控制应用程序中两个输入和两个货币组件的状态。

接下来,导入CurrencyInput 组件并在App 函数中调用它两次,以表示两种货币的inputselect ,并在其相关的input 标记中调用你创建的状态。

import CurrencyInput from "./CurrencyInput";
import { useState } from "react";

function App() {
  const [amount1, setAmount1] = useState(1);
  const [amount2, setAmount2] = useState(1);
  const [currency1, setCurrency1] = useState('USD');
  const [currency2, setCurrency2] = useState('EUR');

  return (
<div>
  <CurrencyInput
        amount={amount1}
        currency={currency1} />
      <CurrencyInput
        amount={amount2}
        currency={currency2} />
</div>
  );
}

使用fixer.io获取真实货币数据

前往Fixer官方网站,如果你还没有他们的账户,点击 "GET YOUR FREE API KEY"。接下来,导航到免费计划,这将引导你到一个注册页面,在那里你将被要求填写你的正确证书。

登录后,你将被重定向到一个页面,看到你的API访问密钥和端点。复制端点数据。你的应用程序将需要通过另一个名为useEffect 的反应钩子来获得最新的货币汇率。

要做到这一点,首先,在你的应用程序终端运行yarn add axios ,以获得对API查询的访问。导入axios 并在.get 函数中使用它。

最好是创建另一个状态函数,在你的端点数据中调节rates 对象,其中包含世界上所有最新货币的凭证。

之后,将rates 的状态存储在get 函数. Lastly, call theratesobject keys in theCurrencyInput` JSX元素内的一个response 函数中。

import { useState, useEffect } from "react";
import axios from "axios";

function App() {
const [rates, setRates] = useState([]);

useEffect(() => {
    axios.get('http://data.fixer.io/api/latest?access_key=106ab470d06b4c14d00c10f864ef62b6')
      .then(response => {
        setRates(response.data.rates);
      })
  }, []);

  return (
<div>
  <CurrencyInput 
  currencies={Object.keys(rates)} 
  />

  <CurrencyInput 
  currencies={Object.keys(rates)} 
  />
</div>
  );
}

下面我们要实现的功能是,输入值能够按照设定的货币自动更新。因此,回到你的CurrentInput.js ,在inputselect 标签中创建一个onChange 函数。

这两个将控制用户输入的值和用户设置的货币的差异。

你还将创建两个函数,onAmountChangedonCurrencyChanged ,它们将执行这些任务,并在你的应用程序中作为propTypes传递。例如,下面的代码是这样的。

import React from 'react'
import propTypes from "prop-types"
const CurrencyInput = (props) => {
    return (
    <input type="text" value={props.amount} onChange={event => props.onAmountChange(event.target.value)}  />
            <select value={props.currency} onChange ={event => props.onCurrencyChange(event.target.value)}>
                {props.currencies.map((currency => (
                    <option value={currency}>{currency}</option>
                )))}
                </select>   
        </div>
    )
}

CurrencyInput.propTypes = {
    onAmountChange: propTypes.func,
    onCurrencyChange: propTypes.func
}

状态管理函数

handleAmount1Change 函数

如果你使用fixer.io 中的rates ,根据设定的货币重新计算数值,将有所帮助。要做到这一点,在App.js 中创建一个函数,将其称为handleAmount1Change ,并传入amount1 作为argument

这个函数将帮助更新第一个输入元素的状态。因此,当第一个输入元素中的值发生变化时,第二个输入元素中的值也将根据用户设置的货币而发生变化。

因此,你将setAmount2 ,等于被amount1 乘以currency2 除以currency1 的汇率。

之后,在CurrencyInput 组件标签中调用onAmountChange ,并传入这个handleAmount1Change 函数。

function handleAmount1Change(amount1) {
  setAmount2(format(amount1 * rates[currency2] / rates[currency1]));
  setAmount1(amount1);
}

return (
<div>
<CurrencyInput
        onAmountChange={handleAmount1Change}
        />
</div>
)

handleCurrency1Change 函数

现在,创建另一个名为handleCurrency1Change 的函数,它将处理select 元素的状态变化,该元素将处理货币的变化。

除了这次在setCurrency1 函数中传入currency1 ,同样的代码也可以工作。然后,在CurrencyInput JSX元素中调用onCurrencyChange 函数,并传入这个handleCurrency1Change 函数。

function handleCurrency1Change(currency1) {
    setAmount2(format(amount1 * rates[currency2] / rates[currency1]));
    setCurrency1(currency1);
  }

  return (
  <div>
  <CurrencyInput
  onCurrencyChange={handleCurrency1Change}
  />
  </div>
  )

handleAmount2Change 函数

这个函数将处理应用程序中第二个输入的状态变化。

传入amount2 ,作为一个argument 。然后,setAmount1 ,等于amount2 乘以currency1 的速率除以currency2 的速率。

接下来,在setAmount2 函数中传入amount2 。之后,在CurrentInput 标签中调用onAmountChange 函数,并传入这个handleAmount2Change 函数。

function handleAmount2Change(amount2) {
   setAmount1(format(amount2 * rates[currency1] / rates[currency2]));
   setAmount2(amount2);
 }

 return (
 <div>
 <CurrencyInput
 onAmountChange={handleAmount2Change}
/>
 </div>
 )

handleCurrency2Change 函数

这个函数将调节第二个select 元素的状态变化,该元素控制用户选择的任何货币。

同样,这里使用的代码与handleAmount2Change 相同,只是你将调用setCurrency2 并传入currency2 。现在,你可以在CurrentInput 标签中调用onCurrencyChange 方法并传入handleCurrency2Change

function handleCurrency2Change(currency2) {
    setAmount1(format(amount2 * rates[currency1] / rates[currency2]));
    setCurrency2(currency2);
  }

  return (
  <div>
  <CurrencyInput
  onCurrencyChange={handleCurrency2Change}
  />
  </div>
  )

TheroundUp 函数

此时,如果你输入一种货币的值,另一种货币的等值可能是一个有许多小数的数字。因此,这个函数将帮助把所有的input 值四舍五入到最多四个小数位。

function roundUp(number) {
   return number.toFixed(4);
 }

之后,在你刚刚创建的四态管理函数中调用这个roundUp 方法。

还有一件事你必须做,就是当用户重新加载页面时,设置应用程序的默认状态。你可以用另一个useEffect 来做到这一点。

useEffect 里面放一个条件语句,说 "如果rates 不是空的,就调用handleAmount1Change ,并将其默认状态设置为1,否则就调用一个init 函数"。

这里是下面的代码。

import { useEffect } from "react";
function App() {
useEffect(() => {
    if (!!rates) {
      function init() {
        handleAmount1Change(1);
      }
      init();
    }
  }, [rates]);
}

在这一点上,这是应用程序的样子。

currency-converter

下面是该应用程序的操作视频。

结论

在构建货币转换器时,我们使用ReactJS及其钩子来实现其功能。我们还用CSS3和React的Material UI组件来设计应用程序的风格。有了这些,你就有了一个功能齐全的货币转换器。