React Project: Membangun Sistem Catatan Keuangan Pribadi
Mengelola keuangan pribadi adalah kebiasaan penting untuk mencapai stabilitas finansial. Dengan React JS, kita bisa membangun aplikasi sederhana yang membantu mencatat pemasukan dan pengeluaran secara real-time.
Pada artikel ini, kita akan membuat Sistem Catatan Keuangan Pribadi menggunakan:
✅ React JS (Functional Components & Hooks)
✅ Local Storage (Menyimpan data tanpa backend)
✅ CSS Modules (Styling yang terorganisir)
✅ React Icons (Tambahan UI yang menarik)
Proyek ini cocok untuk pemula yang ingin belajar state management, form handling, dan penyimpanan data di frontend.
Fitur Aplikasi
-
Tambah Catatan Keuangan (Pemasukan/Pengeluaran)
-
Filter Transaksi (Berdasarkan tanggal/kategori)
-
Hapus & Edit Data
-
Total Saldo Otomatis
-
Penyimpanan Data di Local Storage
Persiapan Project
Pastikan sudah terinstall:
-
Node.js & npm
-
Code Editor (VS Code direkomendasikan)
Buat project React baru:
npx create-react-app finance-tracker cd finance-tracker npm install react-icons uuid
Struktur Folder
src/ ├── components/ │ ├── TransactionForm.js │ ├── TransactionList.js │ └── Balance.js ├── App.js ├── App.css └── index.js
Langkah 1: Membuat Form Input Transaksi
File: components/TransactionForm.js
import { useState } from "react"; import { FaPlus } from "react-icons/fa"; const TransactionForm = ({ addTransaction }) => { const [text, setText] = useState(""); const [amount, setAmount] = useState(""); const [type, setType] = useState("income"); const handleSubmit = (e) => { e.preventDefault(); if (!text || !amount) return; const newTransaction = { id: Date.now(), text, amount: +amount, type, date: new Date().toISOString(), }; addTransaction(newTransaction); setText(""); setAmount(""); }; return ( <form onSubmit={handleSubmit} className="transaction-form"> <h3>Tambah Transaksi Baru</h3> <div> <label>Keterangan</label> <input type="text" value={text} onChange={(e) => setText(e.target.value)} placeholder="Contoh: Gaji Bulanan" /> </div> <div> <label>Jumlah (Rp)</label> <input type="number" value={amount} onChange={(e) => setAmount(e.target.value)} placeholder="Masukkan nominal" /> </div> <div> <label>Tipe Transaksi</label> <select value={type} onChange={(e) => setType(e.target.value)}> <option value="income">Pemasukan</option> <option value="expense">Pengeluaran</option> </select> </div> <button type="submit"> <FaPlus /> Tambah </button> </form> ); }; export default TransactionForm;
Langkah 2: Menampilkan Daftar Transaksi
File: components/TransactionList.js
import { FaTrash, FaEdit } from "react-icons/fa"; const TransactionList = ({ transactions, deleteTransaction }) => { return ( <div className="transaction-list"> <h3>Riwayat Transaksi</h3> {transactions.length === 0 ? ( <p>Tidak ada transaksi</p> ) : ( <ul> {transactions.map((transaction) => ( <li key={transaction.id} className={transaction.type === "income" ? "income" : "expense"} > <span> {transaction.text} - Rp{transaction.amount.toLocaleString()} </span> <div> <button> <FaEdit /> </button> <button onClick={() => deleteTransaction(transaction.id)}> <FaTrash /> </button> </div> </li> ))} </ul> )} </div> ); }; export default TransactionList;
Langkah 3: Menghitung Total Saldo
File: components/Balance.js
const Balance = ({ transactions }) => { const amounts = transactions.map((transaction) => transaction.type === "income" ? transaction.amount : -transaction.amount ); const total = amounts.reduce((acc, item) => acc + item, 0).toLocaleString(); return ( <div className="balance"> <h3>Saldo Anda</h3> <h1>Rp{total}</h1> </div> ); }; export default Balance;
Langkah 4: Mengintegrasikan Semua Komponen
File: App.js
import { useState, useEffect } from "react"; import TransactionForm from "./components/TransactionForm"; import TransactionList from "./components/TransactionList"; import Balance from "./components/Balance"; import "./App.css"; const App = () => { const [transactions, setTransactions] = useState([]); // Load data dari Local Storage saat pertama render useEffect(() => { const savedTransactions = JSON.parse(localStorage.getItem("transactions")); if (savedTransactions) setTransactions(savedTransactions); }, []); // Simpan data ke Local Storage setiap kali ada perubahan useEffect(() => { localStorage.setItem("transactions", JSON.stringify(transactions)); }, [transactions]); const addTransaction = (transaction) => { setTransactions([transaction, ...transactions]); }; const deleteTransaction = (id) => { setTransactions(transactions.filter((t) => t.id !== id)); }; return ( <div className="app"> <h1>Catatan Keuangan Pribadi</h1> <Balance transactions={transactions} /> <TransactionForm addTransaction={addTransaction} /> <TransactionList transactions={transactions} deleteTransaction={deleteTransaction} /> </div> ); }; export default App;
Langkah 5: Styling dengan CSS
File: App.css
body { font-family: 'Arial', sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; } .app { max-width: 600px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } .transaction-form { margin-bottom: 20px; } .transaction-form input, .transaction-form select { width: 100%; padding: 10px; margin: 5px 0 15px; border: 1px solid #ddd; border-radius: 4px; } .transaction-form button { background: #4CAF50; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; } .transaction-list ul { list-style: none; padding: 0; } .transaction-list li { display: flex; justify-content: space-between; padding: 10px; margin: 5px 0; border-radius: 4px; } .income { background: #e8f5e9; border-left: 4px solid #2e7d32; } .expense { background: #ffebee; border-left: 4px solid #c62828; } .balance h1 { color: #2e7d32; }
Kesimpulan
Dalam tutorial ini, kita telah berhasil membuat aplikasi catatan keuangan pribadi menggunakan React JS dengan fitur:
✔ Input transaksi (pemasukan/pengeluaran)
✔ Penyimpanan data di localStorage
✔ Perhitungan saldo otomatis
✔ Hapus transaksi