DEV Community 👩‍💻👨‍💻

Cover image for Using React to create a Budget Manager
Gbadebo ifedayo
Gbadebo ifedayo

Posted on

Using React to create a Budget Manager

Keeping track of daily expenses can be difficult, especially if a lot of items are purchased. As a result, we might not be aware of where particular expenses in our budget are allocated, an app that keeps track of our spending and displays it in a concise, precise manner is therefore essential.
The prerequisites for this project are:

  • Knowledge of CSS, Javascript, and React

  • Latest version of Node.js installed

Getting started

First, we create a new React app in the terminal using the code below.

npx create-react-app Budget manager
Enter fullscreen mode Exit fullscreen mode

Next, we create a folder in the src directory to store all of our app's components and styles.

Image description

In Parent.js file, we import React, the hooks required for our project, and define our "Parent" component.

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

function Parent(){
    return()
}
export default Parent
Enter fullscreen mode Exit fullscreen mode

Next, we utilize the usestate hook to store the the list of purchases made and input text.

    const [purchases,setPurchases]=useState([])
    const [purchase,setPurchase]=useState('')
    const [dates,setDates]=useState('')
    const [category,setCategory]=useState('')
    const [cost,setCost]=useState('')
Enter fullscreen mode Exit fullscreen mode

Building the operations of the app

We have to define of the activities that can be done on the app. We also define functions to update the values of the different sections of a purchase.

    const _purchase=(e)=>{
      setPurchase(e.target.value)
    }
    const _category=(e)=>{
      setCategory(e.target.value)
    }
    const _cost=(e)=>{
      setCost(e.target.value)
    }

    const savePurchase=()=>{
      setPurchases((prevState)=>[...prevState,{
        key:uuid(),
        id:uuid(),
        purchase:purchase,
        category:category,
        date:current_date,
        cost:cost,
      }
      ]);
      setPurchase('')
      setCategory('')
      setCost('')
      setDates('')
    }

    const deletePurchase=(id)=>{
      const filteredPurchases=purchases.filter((purchase)=>{
        return purchase.id !== id;
      });
      setPurchases(filteredPurchases)
    }


Enter fullscreen mode Exit fullscreen mode

In the above code:

  • The savePurchase function appends a new object to the purchase array.

  • The key and id are generated with uuidv4. It is set up using npm install uuidv4 in the terminal, and the following line of code imports it into the project:

import { v4 as uuid } from "uuid";
Enter fullscreen mode Exit fullscreen mode
  • The deletePurchase function takes in an id argument and returns a filtered purchases array.

Creating a statistics section

Our app needs a statistics area to display the budget and total money spent. The cost of each purchase is added to a totalSpent array, and the array's sum is used to determine the total amount spent.
The useEffect hook is used to perform this so that the total is executed each time the purchases array is changed.

    useEffect(()=>{
        const totalArray=purchases.map((item)=>{
          const value= item.cost;
          const num= parseFloat(value);
          return num
        });
        setSpent(
          totalArray.reduce((a,b)=>{
            return a+b
          },0));
    },[purchases])
Enter fullscreen mode Exit fullscreen mode

In order to load the app, we want the proposed budget to be entered by the user. In App.js, we import the Parent component and display the app if a condition is met.

import React,{useState} from 'react'
import Parent from './components/Parent';
function App() {
  const [budget,setBudget]=useState()
  const [page,setPage]=useState(true)
  const updateBudget=(e)=>{
    setBudget(e.target.value);
  }

  const saveBudget=()=>{
    setPage(!page)
  }

  return (
    <div className="App">
      {page? <div className='createbudget'>
            <h1>Get started by creating a new budget</h1>
            <input onChange={updateBudget} type="number"/>
            <button onClick={()=>{saveBudget()}} className="createbudget">create</button></div>
            :
      <Parent budget={budget}/>}
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

The code above displays an input field when page is set to 'true', the useState hook is used to update the value of the budget variable. When the submit button is hit, the value of page is changed to 'false', making the app display the parent component.

Defining our components

Next, we'll define the Createpurchase,Stats, and Tablelist components which will be imported to the Parent component.
Our Createpurchase component displays a form that collects the information to be stored in a purchase, it is passed a number of props, each of which is allocated to a function in the Parent component

import React from 'react'


function Createpurchase({save,pur,categ,cost,update}){
    return(
        <div className='create'>
            <h5>New Purchase</h5>
            <div>
                <label >Purchase</label>
                <input type="text" onChange={pur} value={update.pur} />
            </div>
            <div>
                <label>Category</label>
                <select onChange={categ} value={update.categ}>                    
                    <option>Housing</option>
                    <option>Food</option>
                    <option>Transportation</option>
                    <option>Utilities</option>
                    <option>Medical</option>
                    <option>Personal</option>
                </select>
            </div>

            <div>
                <label >Cost</label>
                <input type="number" onChange={cost} value={update.cost}/>
            </div>
            <button onClick={save}>save</button>
        </div>
    )
}

export default Createpurchase

Enter fullscreen mode Exit fullscreen mode

The stats component displays both the total amount spent and the budget provided by the user.

import React from 'react'


function Stats({spent,budget}){
    return(
        <div className='statistics'>
            <span>
                <h6>Spent</h6>
                <p>${spent}</p>
            </span>

            <span>
                <h6>Budget</h6>
                <p>${budget}</p>
            </span>
        </div>
    )
}



export default Stats
Enter fullscreen mode Exit fullscreen mode

And the Tablelist component comprises of the structure for a purchase saved in the app.

import React from 'react'

function Tablelist({purchase,category,date,cost,del,id}){
    return(
        <div className='list'>
            <p className='purchase'>{purchase}</p>
            <p className='category'>{category}</p>
            <p className='date'>{date}</p>
            <p className='cost'>${cost}</p>
            <button onClick={()=>del(id)}>delete</button>
        </div>
    )
}

export default Tablelist
Enter fullscreen mode Exit fullscreen mode

The Createpurchase, Stat, and Tablelist components have been successfully defined, but they still need to be imported into the Parent.js file. We return our imported components in the Parent component and assign their props to our defined functions.

import Tablelist from "./Tablelist"
import Createpurchase from "./Createpurchase"
import Stats from "./Stats"
  function Parent({budget}){
    return(
        <div>
          <div className="dashboard">
            <Stats spent={spent} budget={budget}/>
          </div>       
          {purchases.map((row)=>(
            <Tablelist purchase={row.purchase} key={row.key} 
             category={row.category} date={row.date} cost= 
             {row.cost} del={deletePurchase} id={row.id}/>
          ))}
            <Createpurchase save={savePurchase} pur={_purchase} 
            categ={_category} cost={_cost}  update={updateValues}/>
        </div>
    )
Enter fullscreen mode Exit fullscreen mode

Adding a cost tracker chart

Our budget manager is almost complete, and the final thing to be added is a chart that displays the total cost spent on each category of purchase. The chart used in this project is gotten from Recharts, it is installed with the following line of code in the terminal:

npm install recharts
Enter fullscreen mode Exit fullscreen mode

To accomplish this, we first create a Chart.js file in our components folder and then import the required resources to include a chart in our app. Next, we add the chart's content.

import React from "react";
import {PieChart,Pie,Tooltip} from 'recharts'


function Chart({data}){
  return (
      <PieChart width={300} height={300}>
        <Pie
          dataKey="value"
          isAnimationActive={false}
          data={data}
          cx="50%"
          cy="50%"
          outerRadius={80}
          fill="#6bbd99"
          label
        />
        <Tooltip />
      </PieChart>
  );
}

export default Chart
Enter fullscreen mode Exit fullscreen mode

An array of values will be assigned to the chart's data prop, which will be displayed in the chart.

<div className="chart">
    <Chart data={chartData}/>
</div>
Enter fullscreen mode Exit fullscreen mode

chartData in the code above is an array that sums the total cost for each category.

Storing purchases using Localstorage

We'll utilize the javascript Localstorage method to ensure that the purchases are not lost if the user leaves the app.

    useEffect(()=>{
      const data=JSON.parse(localStorage.getItem('Purchases'))
      setPurchases(data)
    },[])
    useEffect(()=>{
      localStorage.setItem('Purchases',JSON.stringify(purchases))
    },[purchases])
Enter fullscreen mode Exit fullscreen mode

The first useEffect hook's second argument is an empty square bracket so it runs only when the app is first loaded while the second is only carried out when the purchases array is modified.
Next we style our app in the Parent.css file located in the css folder.

Conclusion

This article demonstrates a simple way of utilising React to build a budget manager app. We are able to do this using React hooks to store various data to be utilised later on, and also perform functions when an array is updated.
You can get the source code for this project on Github , a live demo of the site is on Vercel.

Top comments (1)

Classic DEV Post from 2020:

js visualized

🚀⚙️ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! 🥳

Happy coding!