Today we will learn and practice ReactJs by building a mortgage calculator step by step. This is the project that we will build today 👇

Objectives
The topics we'll cover while building this project are:
- React Functional Components
- Material UI
- User Inputs
- Handling Props
- props destructuring
- useState Hook
And much more! This course is excellent for beginners who want to learn ReactJs by building a real world project.
You can watch this tutorial on YouTube as well if you like:
Table of Contents
- Project Setup
- Folder Structure
- Material UI Theme
- How to Build the Navbar
- Material UI Grid System
- How to Build the Slider Component
- Take a Break
- How to Use the useState Hook
- How to Build the SliderSelect component
- How to Build the TenureSelect component
- How to Build the Result Component
- Conclusion
- My Social Media Links
Project Setup

In order to setup the project we need to install react, material-ui, and other necessary packages.
First create a folder named mortgage-calculator, open it on VS Code, and then run the following command in the terminal:
npx create-react-app .
npm install @mui/material @emotion/react @emotion/styled
npm install --save chart.js react-chartjs-2
App.js
We will remove all the boilerplate code from app.js and keep up to this portion 👇
import React from "react";
function App() {
return <div className="App">Hello everyone</div>;
}
export default App;
Then run this command in the terminal to start the server:
npm start
The project should look totally blank on the web browser now.
Let's start coding

Everything is setup and ready to go. Now we will start building the project :)
Folder Structure

Our folder structure should look like this so that we can easily manage and maintain our files & folders:
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
Here's an image of our project folder structure if you're feeling confused:

Material UI Theme

We will be using the dark theme of Material UI. For that we need to create a file named theme.js in the src folder and add the following code:
theme.js
import { createTheme } from '@mui/material/styles';
export const theme = createTheme({
palette: {
mode: 'dark',
},
})
index.js
Next up, we need to import the theme in the index.js file and wrap the app with the ThemeProvider. Follow along below: 👇
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>
Note: If you don't pass the CssBaseline component we will not be able to see the MUI dark theme.
This is the result so far: 👇

The entire screen will be dark. This means that dark mode has been applied to our project from Material UI.
How to Build the Navbar

Next up, we will be creating a very simple Navbar to show the Logo. For that we need to create a file named Navbar.js in the src/Components folder and add the following code:
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;
Here's a quick explanation of the components used from Material UI:
- AppBar : The Appbar component of Material UI is used for creating a top navigation bar in the user interface. Read more about it here
- Container : The Container component of Material UI is used for creating a container element that can be used to create a responsive layout, and center and contain other elements in a user interface. Read more about it here
- ToolBar : The Toolbar component can contain elements such as buttons, text, and icons, and can also be used for creating a responsive layout that adapts to different screen sizes. Read more about it here
- Typography : Material UI's typography component is used for applying pre-defined typographic styles to text elements. It helps create a consistent and visually pleasing layout with customizable font family, size, weight and spacing. Read more about it here
App.js
Finally, import it to App.js and write the code like this: 👇
import React from "react";
import Navbar from "./Components/Navbar";
function App() {
return (
<div className="App">
<Navbar />
</div>
);
}
export default App;
This is the result so far: 👇

Material UI Grid System

In the finalized project, we can see that our content is divided into 2 portions. On the left we have the slider components and on the right we have the pie chart. This is made possible using the Grid system of material UI.

Not only that, we can also see that the content is responsive on smaller screen sizes. This is also made possible using the Grid system of material UI.

To replicate this, we need to write these things on our App.js file. You can follow along here. 👇
First of all, we need to import all of our required components from Material UI and our components folder:
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";
Next up, we write this code inside the return statement like this: 👇
<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>
Explanation of the code:
- Container: On the
Containerwe wrote something calledsx={{marginTop:4}}. This is the way to add inline-style to a component in Material UI. - Grid: The Grid component is used to create a responsive layout that adapts to different screen sizes.
Grid containerrepresents the parent element andGrid itemrepresents the child element. - On the
Gridcomponent we wrote something calledspacing={5}. This is the way to add spacing between the grid items. - On the
Gridcomponent we also wrotexs={12}which means that the grid item will take up the entire width of the screen on extra small screens. Similarly,md={6}means that the grid item will take up half of the screen on medium and bigger screens. That's how we made our components responsive.
This is the result so far: 👇

How to Build the Slider Component

Next up, we will be creating a slider component to get the input amount from the user. It will look something like this: 👇

For that we need to create a file named SliderComponent.js in the src/Components/Common folder. First let's list out all the props we need to pass to our re-usable slider component:
- label
- min
- max
- defaultValue
- unit
- value
- steps
- amount
- onChange
SliderComponent.js
Let's get going. First of all, import the following components from MUI inside the SliderComponent.js file:
import React from "react";
import Slider from "@mui/material/Slider";
import { Typography } from "@mui/material";
import { Stack } from "@mui/system";
We will be using the Stack component from MUI to stack the components vertically. my is the shorthand for marginY [margin-top & margin-bottom]. We will be using the Typography component from MUI to display the label, unit, and other data. We will be using the Slider component from MUI to display the slider.
Write this small amount of code first, with our props destructured:
const SliderComponent = ({
defaultValue,
min,
max,
label,
unit,
onChange,
amount,
value,
steps
}) => {
return (
<Stack my={1.4}>
</Stack>
)
}
export default SliderComponent
We will write this code to display the label, unit, and amount.
<Stack gap={1}>
<Typography variant="subtitle2">{label}</Typography>
<Typography variant="h5">
{unit} {amount}
</Typography>
</Stack>
We will write this code to display the slider. We will be passing the props to the slider component like this: 👇
<Slider
min={min}
max={max}
defaultValue={defaultValue}
aria-label="Default"
valueLabelDisplay="auto"
onChange={onChange}
value={value}
marks
step={steps}
/>
We will write this code to display the min and max values of the slider. We will be using the Stack component from MUI to stack the components horizontally. direction="row" is the shorthand for flex-direction: row. justifyContent="space-between" is the shorthand for 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>
Good Job so far!
Take a break

Take a break – you deserve it! 🎉
How to Use the useState Hook

We need to use the useState hook from React in our project. But before that, we need to understand what this hook is and why we need to use it.
The useState hook is a built-in React function that allows you to add state to functional components. It returns an array containing two elements: the current state value and a function to update that value. The general syntax of the useState hook is as follows:
const [state, setState] = useState(initialState);
Here's what's going on: 👇
state: The name of the constant or variable that will store the state.setState: A function to update the state.initialState: The initial value of the state.
Example of the useState hook
We will create a toggle button that changes its text between "ON" and "OFF" when clicked.
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;
Here, we initialize the isOn state with an initial value of false. The toggle function updates the isOn state to its opposite value when the user clicks the button. We use a ternary operator to render the text inside the button based on the current value of isOn.
App.js
Now lets come back to our project. First, come over to the App.js file and import the useState hook from React.
import React, { useState } from 'react';
Next up, we will declare a state to store the value of the sliders using the useState hook. We will be passing the initial value of the state as {} inside the useState hook, because we are storing our data as an object.
function App() {
const [data, setData] = useState({})
// other codes are here
}
We're using the useState hook to create a new state variable called data and a function called setData that we can use to update the state.
Next up, we will pass these values as default values for our slider component.
function App() {
const [data, setData] = useState({
homeValue: 3000,
downPayment: 3000 * 0.2,
loanAmount: 3000 * 0.8,
loanTerm: 5,
interestRate: 5,
})
// other codes are here
}
Then, we will be passing the data and setData state as a prop to the SliderSelect component like this: 👇
<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>
How to Build the SliderSelect Component

So now that we have our re-usable SliderComponent ready, let's use it in our SliderSelect.js component. First of all, import the SliderComponent component from the Common folder.
SliderSelect.js
import SliderComponent from "./Common/SliderComponent";
Next up, we will destructure our props that we are receiveing from App.js. And also, we'll create a variable called bank_limit and assign it a value of 10000. This represents the maximum amount of money a person can borrow from our bank.
import React from "react";
import SliderComponent from "./Common/SliderComponent";
const SliderSelect = ({ data, setData }) => {
const bank_limit = 10000;
return (
<div>
</div>
);
};
export default SliderSelect;
Next up, we will use our SliderComponent to display the slider named Home Value. Here we will pass the props like this to the SliderComponent component.
const SliderSelect = ({ data, setData }) => {
const bank_limit = 10000;
return (
<div>
<SliderComponent
onChange={(e, value) => {
setData({
...data,
homeValue: value.toFixed(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>
);
};
Here's the result so far: 👇

In the same way, we will create the sliders for Down Payment and Loan Amount like this: 👇
return (
<div>
{/* other codes are here */}
<SliderComponent
onChange={(e, value) =>
setData({
...data,
downPayment: value.toFixed(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}
/>
<SliderComponent
onChange={(e, value) =>
setData({
...data,
loanAmount: value.toFixed(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>
);
Again, here's the result so far: 👇

Finally we will create the slider for our Interest Rate. You can follow along here: 👇
return (
<div>
{/* other codes are here */}
<SliderComponent
onChange={(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>
);
Here's the result so far: 👇

How to Build the TenureSelect Component
Next up, we will build the TenureSelect component. This component will be used to select the tenure of the loan. It will look like this: 👇

App.js
First of all, pass the data and setData state as a prop to the TenureSelect component like this: 👇
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
Then, import these required components from the MUI library:
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
Then destructure the props that we are receiving from App.js. Also create a function named handleChange that will be used to set the tenure state, like this: 👇
const TenureSelect = ({ data, setData }) => {
const handleChange = (event) => {
setData({...data, loanTerm: event.target.value});
};
return ()
};
export default TenureSelect;
Next up, we will build the TenureSelect component. It will look like this: 👇
return (
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Tenure</InputLabel>
<Select
labelId="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>
);
The result so far: 👇

How to Build the Result Component
Finally we will build the Result component. This component will be used to display the loan installment per month and the pie chart. It will look like this: 👇

App.js
First of all, pass the data state as a prop to the Result component like this: 👇
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
Next up, import the required components like this: 👇
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";
ChartJS.register(ArcElement, Tooltip, Legend);
Then destruct the data state that we are receiving from App.js like this: 👇
const Result = ({ data }) => {
const { homeValue, loanAmount, loanTerm, interestRate } = data;
return ();
};
export default Result;
Next up we will write all of these things that will help us do the calculation: 👇
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;
Then we need this variable to store all the data for our pie chart, like this: 👇
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,
},
],
};
Finally, we will build the Result component. It will look like this: 👇
return (
<Stack gap={3}>
<Typography textAlign="center" variant="h5">
Monthly Payment: $ {monthlyPayment.toFixed(2)}
</Typography>
<Stack direction="row" justifyContent="center">
<div>
<Pie data={pieChartData} />
</div>
</Stack>
</Stack>
);
Here's the final result: 👇

Conclusion

Congratulations for reading until the end! Now you can confidently and efficiently use React JS and Material UI to build cool projects.
You have also learned how to use React's useState hook and how to handle props. I hope you enjoyed this tutorial.
Mentorship Program
If you are interested in learning more about React JS and web development, I am offering a mentorship program. You can check out the details here 👉 Mentor Labs Academy
