使用Fixer.io react和material-UI构建一个货币转换器
货币转换器是一个显示世界上不同货币所代表的等值的应用程序。本文将逐步指导读者用React构建一个货币转换应用程序,并使用Material UI对其组件进行造型。
本文的先决条件
- 一个文本编辑器,例如VSCode。
- 对HTML、CSS和JavaScript编程语言有良好的理解。
- 一个工作中的Node.js安装。
创建React应用程序
前往项目文件夹,运行下面的命令,创建一个新的React应用程序。
npx create-react-app project-name
创建新的React应用程序后,打开文本编辑器,清除App.js 和App.css 中的默认代码,以准备将Material UI整合到你的应用程序中。要在浏览器中本地打开该应用程序,请运行。
npm start
开始使用Material UI
Material UI是一个基于组件的CSS框架,通过为项目的不同部分提供几个相关的组件,帮助开发者构建React应用程序。
MUI组件单独工作。它们是自我支持的,只会显示它们需要显示的样式。因此,它们不依赖于全世界的样式表,如normalize.css。
你需要@material-ui/core ,它可以很容易地与npm 或yarn 一起安装。如果你希望使用图标,你也可以包括@material-ui/icons 包。
以下是将这些包作为依赖项安装在你的应用程序中的命令。
npm install @material-ui/core @material-ui/icons
现在,你可以在你的应用程序的package.json 文件中找到Material UI,如下图所示。

要在你的应用程序中使用任何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 作为参数。然后,创建两个input 和select 元素。在input 和select 标记中分别传入props.amount 和props.currency 作为值。
接下来,设置一个map 函数,该函数将在select 标记中遍历option 标记,我们将称之为currency ,并将其值设置为currency 。
接下来要做的是定义propTypes 。在React中,propTypes 是一种机制,确保组件使用正确的数据排序并传递正确的数据,组件使用正确类型的props ,接收组件获得正确类型的props 。要做到这一点,首先,在终端运行下面的命令。
yarn add prop-types
接下来,导入并调用本应用程序所需的propsTypes ,amount ,作为number ,currency ,作为一个string ,currencies ,作为一个阵列。最后,导出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 函数中调用它两次,以表示两种货币的input 和select ,并在其相关的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 ,在input 和select 标签中创建一个onChange 函数。
这两个将控制用户输入的值和用户设置的货币的差异。
你还将创建两个函数,onAmountChanged 和onCurrencyChanged ,它们将执行这些任务,并在你的应用程序中作为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]);
}
在这一点上,这是应用程序的样子。

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