通过创建贷款计算器学习 React

阅读: 评论:0

通过创建贷款计算器学习 React

通过创建贷款计算器学习 React

大家好,我是若川。我持续组织了近一年的源码共读活动,感兴趣的可以 点此扫码加我微信 lxchuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外:目前建有江西|湖南|湖北籍前端群,可加我微信进群。欢迎星标我的公众号~不错过推文~

今天我们将通过创建一个贷款计算器来学习和实践 ReactJS。这就是我们要创建的项目 👇

  • 这是项目的在线 demo

  • 这是 GitHub 仓库链接

目标

在创建这个项目时,我们将涉及的主题是:

  • React 功能组件

  • Material UI

  • 用户输入

  • 处理 Props

  • Props 解构赋值

  • useState Hook

还有更多!这个教程对于想通过创建一个真实世界的项目来学习 ReactJs 的初学者来说是非常好的。

目录

  • 项目设置

  • 文件夹结构

  • Material UI 主题

  • 如何创建导航条

  • Material UI 网格系统

  • 如何创建 Slider 组件

  • 休息一下

  • 如何使用 useState Hook

  • 如何创建 SliderSelect 组件

  • 如何创建 TenureSelect 组件

  • 如何创建 Result 组件

  • 总结

项目设置

为了设置该项目,我们需要安装 eact、material-ui 和其他必要的软件包。

首先创建一个名为 mortgage-calculator 的文件夹,在 VS Code 上打开它,然后在终端运行以下命令:

npx create-react-app .
npm install @mui/material @emotion/react @emotion/styled
npm install --save chart.js react-chartjs-2

App.js

我们将删除 app.js 中所有的模板代码,保留这部分 👇

import React from "react";function App() {return <div className="App">Hello everyone</div>;
}export default App;

然后在终端运行这个命令来启动服务器:

npm start

该项目现在在 web 浏览器上应该是完全空白的。

开始编程

一切都设置好了,可以开始了。现在,我们将开始构建该项目 :) 

文件夹结构

我们的文件夹结构应该是这样的,这样我们就可以轻松地管理和维护文件和文件夹:

mortgage-calculator/
├── src/
│   ├── Components/
│   │   ├── Common/
│   │   │   └── SliderComponent.js
│   │   ├── Navbar.js
│   │   ├── Result.js
│   │   ├── SliderSelect.js
│   │   ├── TenureSelect.js
│   ├── theme.js
│   ├── App.js
│   ├── index.js
├── .gitignore
├── package.json
└── package-lock.json

如果你感到困惑,这里有一张我们的项目文件夹结构的图片:

Material UI 主题

我们将使用 Material UI 的深色主题。为此,我们需要在 src 文件夹中创建一个名为 theme.js 的文件,并添加以下代码:

theme.js

import { createTheme } from '@mui/material/styles';export const theme = createTheme({palette: {mode: 'dark',},
})

index.js

接下来,我们需要在 index.js 文件中导入 theme,并用 ThemeProvider 来包含应用程序。下面就跟着做吧:👇

import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import { theme } from "./theme";<React.StrictMode><ThemeProvider theme={theme}><App /><CssBaseline /></ThemeProvider>
</React.StrictMode>

注意:如果你不传递 CssBaseline 组件,我们将无法看到 MUI 的深色主题。

这是目前的结果:👇

整个屏幕将是黑的。这意味着我们的项目已经应用了 Material UI 深色模式。

如何创建 Navbar

接下来,我们将创建一个非常简单的导航条来显示 logo。为此,我们需要在 src/Components 文件夹中创建一个名为 Navbar.js 的文件,并添加以下代码:

Navbar.js

import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import { Container } from "@mui/system";const Navbar = () => {return (<AppBar position="static"><Container maxWidth='xl'><Toolbar><Typography variant="h5">Bank of React</Typography></Toolbar></Container></AppBar>);
};export default Navbar;

下面是对 Material UI 中使用的组件的简单解释:

  • AppBar:Material UI 的 AppBar 组件用于在用户界面上创建一个顶部导航栏。点击这里了解更多。

  • Container:Material UI 的 Container 组件用于创建一个容器元素,该元素可用于创建一个响应式布局,并在用户界面中集中和包含其他元素。点击这里了解更多。

  • ToolBar:Toolbar 组件可以包含诸如按钮、文本和图标等元素,也可以用来创建一个适应不同屏幕尺寸的响应式布局。点击这里了解更多。

  • Typography:Material UI 的 typography 组件用于将预定义的排版样式应用于文本元素。它可以帮助创建一个一致的、视觉上赏心悦目的布局,具有可定制的字体、大小、粗细和间距。点击这里了解更多。

App.js

最后,将其导入 App.js,并这样写代码:👇

import React from "react";
import Navbar from "./Components/Navbar";function App() {return (<div className="App"><Navbar /></div>);
}export default App;

这是目前为止的结果:👇

Material UI 网格系统

在最终完成的项目中,我们可以看到内容被分成了两部分。左边有滑块组件,右边有饼图。这是用 Material UI 的网格系统实现的。

不仅如此,我们还可以看到,内容在较小的屏幕尺寸上是响应式的。这也是通过使用 Material UI 网格系统实现的。

为了复制这一点,我们需要在 App.js 文件上写上这些东西。你可以在这里跟着做。👇

首先,我们需要从 Material UI 和组件文件夹中导入所有需要的组件:

import React, { useState } from "react";
import { Grid } from "@mui/material";
import { Container } from "@mui/system";
import Navbar from "./Components/Navbar";
import Result from "./Components/Result";
import SliderSelect from "./Components/SliderSelect";
import TenureSelect from "./Components/TenureSelect";

接下来,我们在 return 语句里面写这段代码:👇

<div className="App"><Navbar /><Container maxWidth="xl" sx={{marginTop:4}}><Grid container spacing={5} alignItems="center"><Grid item xs={12} md={6}><SliderSelect /><TenureSelect /></Grid><Grid item xs={12} md={6}><Result/></Grid></Grid></Container>
</div>

对这段代码的解释:

  • Container:在 Container 上,我们写了 sx={{marginTop:4}}。这是在 Material UI 中为组件添加内联样式的方法。

  • Grid:Grid 组件被用来创建一个适应不同屏幕尺寸的响应式布局。Grid container 代表父元素,Grid item 代表子元素。

  • 在 Grid 组件上,我们写了 spacing={5}。这是在网格项之间添加间距的方法。

  • 在 Grid 组件上,我们还写了 xs={12},这意味着在超小屏幕上,网格项将占据整个屏幕的宽度。同样地,md={6} 意味着在中等和较大的屏幕上,网格项将占到屏幕的一半。这就是我们如何使组件具有响应性。

这是目前为止的结果:👇

如何创建 Slider 组件

接下来,我们将创建一个滑块组件来获取用户的输入金额。它看起来将是这样的:👇

为此,我们需要在 src/Components/Common 文件夹中创建一个名为 SliderComponent.js 的文件。首先,让我们列出所有需要传递给可重用的滑块组件的 props:

  • label

  • min

  • max

  • defaultValue

  • unit

  • value

  • steps

  • amount

  • onChange

SliderComponent.js

我们开始吧。首先,在 SliderComponent.js 文件中从 MUI 导入以下组件:

import React from "react";
import Slider from "@mui/material/Slider";
import { Typography } from "@mui/material";
import { Stack } from "@mui/system";

我们将使用 MUI 的 Stack 组件来垂直堆叠组件。mymarginY [margin-top & margin-bottom] 的缩写。我们将使用 MUI 的 Typography 组件来显示标签、单位和其他数据。我们将使用 MUI 的 Slider 组件来显示滑块。

先写这一小段代码,解构 props:

const SliderComponent = ({defaultValue,min,max,label,unit,onChange,amount,value,steps
}) => {return (<Stack my={1.4}></Stack>)
}export default SliderComponent

我们将编写这段代码来显示标签、单位和金额。

<Stack gap={1}><Typography variant="subtitle2">{label}</Typography><Typography variant="h5">{unit} {amount}</Typography>
</Stack>

编写这段代码来显示滑块,并像这样把 props 传递给滑块组件:👇

<Slidermin={min}max={max}defaultValue={defaultValue}aria-label="Default"valueLabelDisplay="auto"onChange={onChange}value={value}marksstep={steps}
/>

我们将编写这段代码来显示滑块的最小和最大值。我们将使用 MUI 的 Stack 组件来水平堆叠组件。direction="row"flex-direction: row 的缩写。justifyContent="space-between"justify-content: space-between 的缩写。

<Stack direction="row" justifyContent="space-between"><Typography variant="caption" color="text.secondary">{unit} {min}</Typography><Typography variant="caption" color="text.secondary">{unit} {max}</Typography>
</Stack>

到目前为止,干得不错!

休息一下

休息一会儿吧——你值得!🎉

如何使用 useState Hook

我们需要在我们的项目中使用 useState hook。但在此之前,我们需要了解它是什么以及为什么我们需要使用它。

useState hook 是一个内置的 React 函数,允许你向功能组件添加状态。它返回一个包含两个元素的数组:当前状态值和一个更新该值的函数。useState hook 的一般语法如下:

const [state, setState] = useState(initialState);

其中👇

  • state:将存储状态的常量或变量的名称

  • setState:一个更新状态的函数

  • initialState:状态的初始值

useState hook 的例子

我们将创建一个切换按钮,点击它时,它的文本在 “ON” 和 “OFF” 之间切换。

import React, { useState } from 'react';const ToggleButton = () => {const [isOn, setIsOn] = useState(false);const toggle = () => setIsOn(!isOn)return (<button onClick={toggle}>{isOn ? 'ON' : 'OFF'}</button>);
};export default ToggleButton;

在这里,我们初始化 isOn 状态的初始值为 false。当用户点击按钮时,toggle 函数将 isOn 状态更新为其相反的值。我们使用一个三元操作符,根据 isOn 的当前值来渲染按钮内的文本。

App.js

现在让我们回到我们的项目中来。首先,在 App.js 文件中,从 React 导入 useState hook。

import React, { useState } from 'react';

接下来,我们将使用 useState hook 声明一个状态来存储滑块的值。我们将在 useState hook 中以 {} 的形式传递状态的初始值,将数据存储为一个对象。

function App() {const [data, setData] = useState({})// other codes are here
}

我们使用  useState hook 来创建一个名为 data 的新状态变量和一个名为 setData 的函数,我们可以用它来更新这个状态。

接下来,我们将把这些值作为默认值传递给滑块组件。

function App() {const [data, setData] = useState({homeValue: 3000,downPayment: 3000 * 0.2,loanAmount: 3000 * 0.8,loanTerm: 5,interestRate: 5,})// other codes are here
}

然后,我们将把 datasetData 状态作为一个 prop 传递给 SliderSelect 组件,像这样:👇

<div className="App"><Navbar /><Container maxWidth="xl" sx={{marginTop:4}}><Grid container spacing={5} alignItems="center"><Grid item xs={12} md={6}>{/* this is where we write the code  👇 */}<SliderSelect data={data} setData={setData}/><TenureSelect /></Grid><Grid item xs={12} md={6}><Result/></Grid></Grid></Container>
</div>

如何创建 SliderSelect 组件

所以现在我们已经准备好了可重复使用的 SliderComponent,将在 SliderSelect.js 组件中使用它。首先,从 Common 文件夹中导入 SliderComponent 组件。

SliderSelect.js

import SliderComponent from "./Common/SliderComponent";

接下来,我们将对从 App.js 收到的 prop 进行解构。同时,创建一个名为 bank_limit 的变量,并给它一个 10000 的值。这代表了一个人可以从我们的银行借到的最大数额的钱。

import React from "react";
import SliderComponent from "./Common/SliderComponent";const SliderSelect = ({ data, setData }) => {const bank_limit = 10000;return (<div></div>);
};export default SliderSelect;

接下来,我们将使用 SliderComponent 来显示名为 Home Value 的滑块。在这里,我们将像这样把 props 传递给 SliderComponent 组件。

const SliderSelect = ({ data, setData }) => {const bank_limit = 10000;return (<div><SliderComponentonChange={(e, value) => {setData({...data,homeValue: Fixed(0),downPayment: (0.2 * value).toFixed(0),loanAmount: (0.8 * value).toFixed(0),});}}defaultValue={data.homeValue}min={1000}max={bank_limit}steps={100}unit="$"amount={data.homeValue}label="Home Value"value={data.homeValue}/></div>);
};

这是目前为止的结果:👇

我们将以同样的方式为 Down PaymentLoan Amount 创建滑块,像这样:👇

return (<div>{/* other codes are here */}<SliderComponentonChange={(e, value) =>setData({...data,downPayment: Fixed(0),loanAmount: (data.homeValue - value).toFixed(0),})}defaultValue={data.downPayment}min={0}max={data.homeValue}steps={100}unit="$"amount={data.downPayment}label="Down Payment"value={data.downPayment}/><SliderComponentonChange={(e, value) =>setData({...data,loanAmount: Fixed(0),downPayment: (data.homeValue - value).toFixed(0),})}defaultValue={data.loanAmount}min={0}max={data.homeValue}steps={100}unit="$"amount={data.loanAmount}label="Loan Amount"value={data.loanAmount}/></div>);

这是目前为止的结果:👇

最后,我们将为 Interest Rate 创建滑块。你可以在这里跟着做:👇

return (<div>{/* other codes are here */}<SliderComponentonChange={(e, value) =>setData({...data,interestRate: value,})}defaultValue={data.interestRate}min={2}max={18}steps={0.5}unit="%"amount={data.interestRate}label="Interest Rate"value={data.interestRate}/></div>);

结果如下:👇

如何创建 TenureSelect 组件

接下来,我们将创建 TenureSelect 组件。这个组件将被用来选择贷款的期限。它看起来像这样:👇

App.js

首先,像这样把 datasetData 状态作为一个 prop 传递给 TenureSelect 组件:👇

return (<div className="App"><Navbar /><Container maxWidth="xl" sx={{marginTop:4}}><Grid container spacing={5} alignItems="center"><Grid item xs={12} md={6}><SliderSelect data={data} setData={setData} />{/* this is where we write the code  👇 */}<TenureSelect data={data} setData={setData}/></Grid><Grid item xs={12} md={6}><Result data={data}/></Grid></Grid></Container></div>
);

TenureSelect.js

然后,从 MUI 库中导入这些所需的组件:

import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";

然后解构我们从 App.js 接收的 props,同时创建一个名为 handleChange 的函数,它将被用来设置 tenure 状态,像这样:👇

const TenureSelect = ({ data, setData }) => {const handleChange = (event) => {setData({...data, loanTerm: event.target.value});};return ()
};export default TenureSelect;

接下来,我们将创建 TenureSelect 组件。它看起来像这样:👇

return (<FormControl fullWidth><InputLabel id="demo-simple-select-label">Tenure</InputLabel><SelectlabelId="demo-simple-select-label"id="demo-simple-select"value={data.loanTerm}label="Tenure"defaultValue={5}onChange={handleChange}><MenuItem value={5}>5 years</MenuItem><MenuItem value={10}>10 years</MenuItem><MenuItem value={15}>15 years</MenuItem><MenuItem value={20}>20 years</MenuItem><MenuItem value={25}>25 years</MenuItem></Select></FormControl>
);

结果如下:👇

如何创建 Result 组件

最后,我们将创建 Result 组件。这个组件将用于显示每月的贷款分期付款和饼图。它看起来像这样:👇

App.js

首先,像这样把 data 状态作为一个 prop 传递给 Result 组件:👇

return (<div className="App"><Navbar /><Container maxWidth="xl" sx={{marginTop:4}}><Grid container spacing={5} alignItems="center"><Grid item xs={12} md={6}><SliderSelect data={data} setData={setData} /><TenureSelect data={data} setData={setData}/></Grid><Grid item xs={12} md={6}>{/* this is where we write the code  👇 */}<Result data={data}/></Grid></Grid></Container></div>
);

Result.js

接下来,像这样导入所需的组件:👇

import React from "react";
import { Stack, Typography } from "@mui/material";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import { Pie } from "react-chartjs-2";ister(ArcElement, Tooltip, Legend);

然后像这样解构我们从 App.js接收的数据状态:👇

const Result = ({ data }) => {const { homeValue, loanAmount, loanTerm, interestRate } = data;return ();
};export default Result;

接下来我们将写出所有帮助我们进行计算的东西:👇

const totalLoanMonths = loanTerm * 12;const interestPerMonth = interestRate / 100 / 12;const monthlyPayment =(loanAmount *interestPerMonth *(1 + interestPerMonth) ** totalLoanMonths) /((1 + interestPerMonth) ** totalLoanMonths - 1);const totalInterestGenerated = monthlyPayment * totalLoanMonths - loanAmount;

然后我们需要这个变量来存储饼图的所有数据,像这样:👇

const pieChartData = {labels: ["Principle", "Interest"],datasets: [{label: "Ratio of Principle and Interest",data: [homeValue, totalInterestGenerated],backgroundColor: ["rgba(255, 99, 132, 0.2)", "rgba(54, 162, 235, 0.2)"],borderColor: ["rgba(255, 99, 132, 1)", "rgba(54, 162, 235, 1)"],borderWidth: 1,},],
};

最后,我们将创建 Result 组件,它是这样的:👇

return (<Stack gap={3}><Typography textAlign="center" variant="h5">Monthly Payment: $ {Fixed(2)}</Typography><Stack direction="row" justifyContent="center"><div><Pie data={pieChartData} /></div></Stack></Stack>
);

结果如下:👇

总结

祝贺你读到最后!现在你可以自信地、有效地使用 ReactJS 和 Material UI 来创建很酷的项目。

你还学会了如何使用 React 的 useState hook,以及如何处理 props。我希望你喜欢这个教程。


原文链接:/

作者:Joy Shaheb

译者:Chengjun.L

本文发布于:2024-02-02 22:29:24,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170688416246858.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:计算器   贷款   React
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23