Create an Expense Tracker using React-Native
Last Updated :
26 Jul, 2024
Expense Tracker application using React-Native is an application where users can manage the transactions made and then visualize the expenditure with the help of a pie chart. The users can add transactions while providing the category of expenditure. The application will run on any device and is the scope of a much larger application. The application is cross-platform which means it can run on any application.
Preview of final output: Let us have a look at how the final output will look like.

Prerequisites and Technologies Used
Approach
- The application will have a single screen.
- The application will have a pie chart and an add button.
- On pressing the add button, a form will open. The form contains the expense name, amount and category from a select option.
- Finally, on pressing add, the expense list and chart are updated.
- The expenses are displayed in the form of a scrollable list.
- Each expense tile will also have a delete button to remove it from the list.
- We are using react-native-picker for a dropdown.
- We used react-native-chart-kit
Steps to create React-Native Application
Step 1: Create the project
npx create-expo-app expense-tracker
Step 2: Navigate to the project
cd expense-tracker
Step 3: Install the required plugins
- react-native-chart-kit: To generate a chart of expenses
- @react-native-picker/picker: To create a dropdown
npx expo install react-native-chart-kit @react-native-picker/picker
Step 4: Create the following required files:
- add_expense.js: For add expense form
- expense_component.js :To display the list of form
- styles.js: Stylesheet of the application
Project Structure:

The updated dependencies in package.json file will look like.
"dependencies": {
"expo": "~49.0.11",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.4",
"react-native-chart-kit": "^6.12.0",
"@react-native-picker/picker": "2.4.10"
},
"devDependencies": {
"@babel/core": "^7.20.0"
}
Example: We will place the state variables in the App.js and load all the components declared in the respective files here. The code is divided into different files for making it readable.
App.js
JavaScript
import { StatusBar } from "expo-status-bar";
import { useEffect, useState } from "react";
import { Button, SafeAreaView, Text, View } from "react-native";
import { PieChart } from "react-native-chart-kit";
import styles from "./styles";
import Addform from "./add_expense";
import ExpenseComponent from "./expense_component";
export default function App() {
// Define state variables using the useState hook
const [name, setName] = useState("");
const [amount, setAmount] = useState("");
const [category, setCategory] = useState("Food");
const [expenses, setExpenses] = useState([]);
const categories = ["Food", "Clothes", "Bills", "Others"];
const [addForm, setAddForm] = useState(false);
// Function to open the add expense form
const addExpense = () => {
setAddForm(true);
};
// Initialize the chart data with default values
const [chartData, setChartData] = useState([
{
name: "Food",
amount: 0,
color: "#e62d20",
legendFontColor: "#7F7F7F",
legendFontSize: 15,
},
{
name: "Clothes",
amount: 0,
color: "#27e620",
legendFontColor: "#7F7F7F",
legendFontSize: 15,
},
{
name: "Bills",
amount: 0,
color: "#1c6bd9",
legendFontColor: "#7F7F7F",
legendFontSize: 15,
},
{
name: "Others",
amount: 0,
color: "#5adbac",
legendFontColor: "#7F7F7F",
legendFontSize: 15,
},
]);
// Render the components and UI
return (
<SafeAreaView style={styles.container}>
<StatusBar style="auto" />
<Text style={styles.heading}>Welcome to GeeksforGeeks</Text>
<Text style={styles.heading2}>
Expense Tracker using React-Native
</Text>
{/* Render the PieChart component with data */}
<PieChart
data={chartData}
width={300}
height={200}
chartConfig={{
backgroundGradientFrom: "#1E2923",
backgroundGradientTo: "#08130D",
color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`,
}}
accessor="amount"
backgroundColor="transparent"
paddingLeft="15"
absolute
/>
{/* Conditional rendering: If addForm is true,
render the Addform component */}
{addForm == true ? (
<Addform
name={name}
setName={setName}
amount={amount}
setAmount={setAmount}
category={category}
setCategory={setCategory}
categories={categories}
setExpenses={setExpenses}
expenses={expenses}
chartData={chartData}
setChartData={setChartData}
setAddForm={setAddForm}
/>
) : (
/* If addForm is false, render the "Add Expense" button */
<View style={styles.row}>
<Button
onPress={addExpense}
color="green"
style={styles.addButton}
title="Add Expense"
/>
</View>
)}
{/* Render the ExpenseComponent */}
<ExpenseComponent
expenses={expenses}
setExpenses={setExpenses}
chartData={chartData}
setChartData={setChartData}
/>
</SafeAreaView>
);
}
JavaScript
// add_expense.js
import { Picker } from "@react-native-picker/picker";
import { Button, Text, TextInput, View } from "react-native";
import styles from "./styles";
// Define the Addform component which is used to add new expenses
export default function Addform({
name,
setName,
amount,
setAmount,
category,
setCategory,
categories,
setExpenses,
expenses,
chartData,
setChartData,
setAddForm,
}) {
return (
<View>
<Text style={styles.heading3}>Add Form</Text>
{/* Input field for expense name */}
<Text style={styles.label}>Expense Name</Text>
<TextInput
onChangeText={(value) => setName(value)}
value={name}
style={styles.textInput}
placeholder="Enter the expense name"
/>
{/* Input field for expense amount */}
<Text style={styles.label}>Amount</Text>
<TextInput
keyboardType="numeric"
onChangeText={(value) => {
// Ensure only numeric values are entered for the amount
value = value.replace(/[^0-9]/g, "");
setAmount(value);
}}
value={amount}
style={styles.textInput}
placeholder="Amount"
/>
{/* Dropdown to select expense category */}
<Text style={styles.label}>Category</Text>
<Picker
style={styles.textInput}
selectedValue={category}
onValueChange={(itemValue, itemIndex) => setCategory(itemValue)}
>
{categories.map((category, index) => {
return (
<Picker.Item
key={index}
label={category}
value={category}
/>
);
})}
</Picker>
{/* Buttons to add or cancel expense */}
<View style={styles.row}>
{/* Add Expense button */}
<Button
onPress={() => {
let amountNumber = parseInt(amount);
if (amountNumber <= 0 || name == "") {
// Validation: Ensure valid amount
// and name are entered
alert("Please enter a valid amount and name");
return;
}
// Add the new expense to the list of expenses
setExpenses([
...expenses,
{
id: new Date().getTime(),
category,
name,
amount: amountNumber,
},
]);
// Update the chart data to reflect the new expense
let newChartData = [...chartData];
let index = newChartData.findIndex(
(item) => item.name == category
);
newChartData[index].amount += amountNumber;
setChartData(newChartData);
// Reset form fields and close the form
setAddForm(false);
setName("");
setAmount("");
setCategory("Food");
}}
title="Add Expense"
/>
{/* Cancel button to close the form
without adding an expense */}
<Button
onPress={() => {
setAddForm(false);
}}
title="Cancel"
/>
</View>
</View>
);
}
JavaScript
// expense_component.js
import { Alert, Button, ScrollView, Text, View } from "react-native";
import styles from "./styles";
export default function ExpenseComponent({
expenses,
setExpenses,
chartData,
setChartData,
}) {
return (
<ScrollView
style={{
marginBottom: 80,
}}
>
{expenses.map((expense) => {
console.log(expense);
return (
<ExpenseListTile
key={expense.id}
expense={expense}
chartData={chartData}
expenses={expenses}
setChartData={setChartData}
setExpenses={setExpenses}
/>
);
})}
</ScrollView>
);
}
const ExpenseListTile = ({
expense,
expenses,
setExpenses,
chartData,
setChartData,
}) => {
return (
<View style={styles.expenseTile}>
<Text style={styles.expenseTileText}>{expense.name}</Text>
<Text style={styles.expenseTileText}>{expense.category}</Text>
<Text style={styles.expenseTileText}>{expense.amount}</Text>
<Button
onPress={() => {
Alert.alert("Delete", "Are you sure you want to delete?", [
{
text: "Yes",
onPress: () => {
let newExpenses = [...expenses];
let index = newExpenses.findIndex(
(item) => item.id == expense.id
);
newExpenses.splice(index, 1);
setExpenses(newExpenses);
let newChartData = [...chartData];
let index2 = newChartData.findIndex(
(item) => item.name == expense.category
);
newChartData[index2].amount -= expense.amount;
setChartData(newChartData);
},
},
{
text: "No",
onPress: () => {
console.log("No");
},
},
]);
}}
title="Delete"
/>
</View>
);
};
JavaScript
// styles.js
import { StyleSheet } from "react-native";
// styles sheet to store all the styles in one place
const styles = StyleSheet.create({
row: {
flexDirection: "row",
justifyContent: "space-evenly",
},
container: {
backgroundColor: "#fff",
height: "100%",
marginTop: 50,
},
heading: {
color: "green",
fontSize: 30,
textAlign: "center",
fontWeight: "bold",
},
addButton: {
padding: 10,
margin: 10,
},
heading2: {
color: "black",
fontSize: 25,
textAlign: "center",
fontWeight: "bold",
},
heading3: {
color: "black",
fontSize: 20,
textAlign: "center",
},
label: {
color: "black",
fontSize: 16,
textAlign: "left",
fontWeight: "bold",
marginLeft: 10,
},
expenseTile: {
// column with 3 cells
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: "lightgrey",
width: "95%",
padding: 10,
margin: 10,
},
expenseTileText: {
fontSize: 20,
width: "22%",
textAlign: "center",
},
formAdd: {
// display: "none",
},
textInput: {
borderRadius: 12,
borderColor: "black",
borderWidth: 1,
padding: 10,
margin: 10,
},
});
export default styles;
Steps to run the application:
Step 1: Run the application
npx expo start
Step optional: To run on Web, you need to install the following packages
npx expo install react-dom react-native-web @expo/webpack-config
Step 2: To run on web, press w on Terminal will application is running. For Android/IOS, install the Expo app and scan the QR code or enter the link of Metro in the Terminal.
Output:
Explanation
- The ExpenseComponent holds each of the expense element and displays them.
- chartData is used to display the chart and expenses used to hold the individual expenses.
- We toggle the form using addForm boolean variable.
- On pressing Add Button, it is toggled so that we can show/hide the form.
Similar Reads
Create a Task Manager App using React-Native
In this article, we'll walk you through the process of building a basic Task Manager app using React Native. The application enables users to effortlessly create, edit, complete/incomplete, and delete tasks, providing an uncomplicated yet impactful introduction to ReÂact Native's mobile app develop
7 min read
Create a Tic-Tac-Toe using React-Native
In this article, we will learn how to build a Tic-Tac-Toe game using React-Native. React Native enables the application to run a single code base on multiple platforms like Android, IOS, etc. Developing the TicTacToe game application allows us to learn basic styling, app logic, user interaction, and
4 min read
Expense Tracker using React
The Expense Tracker project is a web application developed using React. Its main purpose is to assist users in keeping track of their expenses. With this app, users can easily add, and delete expenses to view a summary of their spending habits as well and it will show the available balance the user
7 min read
Create a Book Store using React-Native
React-Native is a flexible frameworks for building mobile applications. We will develop a Book Store application, which allows users to search for a specific book, and store the book in the application. If the user wants to remove the book from the stored list, they can easily remove it by navigatin
6 min read
Create an Employee Management using React-Native
Creating the Employee Management Application using React-Native is skill developing project. In this project, the application admin can manage the employees by adding them dynamically, updating the details, and deleting the employee as per the requirement. In this article, we will develop this Emplo
6 min read
Create a Text Editor App using React-Native
In this article, we are going to implement a text editor app using React Native. It will contain multiple text formatting functionalities like bold, italic, underline, etc. We will implement Editor with a library called "react-native-pell-rich-editor." Preview of final output: Let us have a look at
3 min read
Create a News Reader app using React-Native
Creating the News Reader application using React-Native language is an exciting project. Using this project, the users can read the news in the application itself, by filtering them according to the categories as per their interest. In this article, we will develop the complete News Reader applicati
5 min read
Build an Expense Tracker using JavaScript
In this article, we will demonstrate the creation of a basic expense tracker web page using JavaScript. An Expense Tracker can be useful in keeping a record of the expenditure, you can maintain a list of expenses along with individual and total amounts. Just enter a name and amount and you can store
5 min read
Create a Food Reciepe App using React-Native
In this React-Native article, we will be developing an interactive Food Recipe Application. In this application, the users can be able to search for any food recipe in the search box. Then, according to the search query, the results will be fetched through an API and will be displayed in the applica
5 min read
Create Timeline App using React-Native
A Timeline App is a software application designed to display events in chronological order. The primary purpose of this timeline app is to present a visual representation of a sequence of events. In this article, we are going to implement a TimeLine App using React Native. It allows users to easily
4 min read