I’m excited to share that I recently built a fully functional expense tracker using React! It’s a simple yet powerful tool that allows users to log their expenses and income, providing a clear picture of their financial habits. Today, I’ll take you through my journey of creating this project and explain how I built it step by step.
Build an Expense Tracker
We all need to manage our finances better, and an expense tracker is an excellent way to keep tabs on where our money is going. For me, it was also an opportunity to enhance my React skills and work on a real-world application that could be useful in daily life. This project helped me learn about state management, user input handling, and the basics of data visualization.
Key Features of the Expense Tracker
- Add Expense: Users can log their expenses by specifying the purpose and amount spent.
- Record Income: Users can add sources of income, such as gifts, salaries, or freelance payments.
- Expense and Income Overview: A summary of total income, total expenses, and the remaining balance.
- Filter by Date: Users can filter expenses and income entries by date.
- Responsive Design: The app works seamlessly on both desktop and mobile devices.
Tools and Technologies Used
- React: For building the user interface.
- CSS/Bootstrap: For styling the application.
- useState and useEffect: For state management and side effects.
- LocalStorage: To persist data between sessions.
- FontAwesome Icons: For adding intuitive icons to the UI.
Guide to Building the App
Setting Up the Project
First, I created a new React app using Create React App:
npx create-react-app expense-tracker
cd expense-tracker
I cleaned up the default files and organized the folder structure into components
, styles
, and utils
directories.
Designing the User Interface
I started by creating the layout of the app. The app consists of three main sections:
- Header: Displays the app title and total balance.
- Expense and Income Form: Allows users to input their data.
- Transaction List: Shows all logged transactions.
Here’s the JSX structure for the layout:
function App() {
return (
<div className="container">
<header>
<h1>Expense Tracker</h1>
<h2>Balance: $0</h2>
</header>
<main>
<TransactionForm />
<TransactionList />
</main>
</div>
);
}
Adding State Management
I used the useState
hook to manage the app’s state. Here’s a simplified version:
const [transactions, setTransactions] = useState([]);
const [balance, setBalance] = useState(0);
function addTransaction(transaction) {
setTransactions([...transactions, transaction]);
updateBalance(transaction);
}
function updateBalance(transaction) {
const newBalance = transaction.type === 'income' ? balance + transaction.amount : balance - transaction.amount;
setBalance(newBalance);
}
Building the Transaction Form
The form lets users add expenses and income. I handled input changes using controlled components and onSubmit
for form submission:
function TransactionForm({ addTransaction }) {
const [description, setDescription] = useState('');
const [amount, setAmount] = useState('');
const [type, setType] = useState('expense');
function handleSubmit(e) {
e.preventDefault();
addTransaction({ description, amount: parseFloat(amount), type });
setDescription('');
setAmount('');
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Description"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<input
type="number"
placeholder="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<select value={type} onChange={(e) => setType(e.target.value)}>
<option value="expense">Expense</option>
<option value="income">Income</option>
</select>
<button type="submit">Add</button>
</form>
);
}
Displaying Transactions
To list all transactions, I created the TransactionList
component:
function TransactionList({ transactions }) {
return (
<ul>
{transactions.map((transaction, index) => (
<li key={index}>
{transaction.description} - ${transaction.amount} ({transaction.type})
</li>
))}
</ul>
);
}
Adding LocalStorage
To ensure data persistence, I used localStorage
to save and retrieve transactions:
useEffect(() => {
const storedTransactions = JSON.parse(localStorage.getItem('transactions'));
if (storedTransactions) {
setTransactions(storedTransactions);
}
}, []);
useEffect(() => {
localStorage.setItem('transactions', JSON.stringify(transactions));
}, [transactions]);
Explanation
The expense tracker works great, but there are several enhancements I’d like to add:
- Charts and Graphs: Visualize spending habits with pie charts and bar graphs.
- Authentication: Allow multiple users to save their data securely.
- Category Tags: Enable users to tag transactions by categories (e.g., food, rent, entertainment).
- Export Feature: Provide an option to export data to CSV.
This project was a fantastic learning experience and taught me the importance of building reusable components, managing state effectively, and enhancing user experience. If you’re interested in building a similar project or have suggestions for improvement.
Conclusion
Building this expense tracker was a rewarding journey that combined practical functionality with skill enhancement. It not only simplifies financial management but also showcases the power of React in creating dynamic, user-friendly applications. I’m thrilled with the outcome and look forward to refining it further. If you’re inspired to build your own or have ideas for improvements.