duit/LEARNING_MATERIALS.md
Dita Aji Pratama 0e35047375 docs: comprehensive learning materials
- Prerequisites (Node.js, Expo, VS Code)
- Detailed folder structure explanation
- Materi per commit dengan code snippets
- Cara menggunakan untuk pembelajaran
- Cara run aplikasi (Android, iOS, Web, Smartphone)
- Debugging tips
- Complete commit list
2026-04-18 12:30:09 +07:00

13 KiB

Finance Tracker - Materi Pembelajaran React Native

Project ini adalah aplikasi penghitung income dan expense keuangan untuk pembelajaran React Native. Setiap commit merepresentasikan satu tahap pembelajaran yang dapat diikuti oleh murid dan pengajar.


Prerequisites

Sebelum memulai, pastikan komputer Anda sudah terinstall:

  1. Node.js (versi 18 atau terbaru)

  2. Expo CLI

    npm install -g expo-cli
    
  3. Code Editor (VS Code direkomendasikan)

  4. Untuk Running di Android:

    • Android Studio (dengan SDK)
    • Atau gunakan Expo Go di smartphone

Struktur Folder Project

duit/
├── app/                       # File routing (expo-router)
│   ├── _layout.tsx            # Root layout
│   └── (tabs)/                # Tab navigation
│       ├── _layout.tsx        # Tab config
│       ├── index.tsx         # Home screen
│       └── explore.tsx        # Stats screen
├── components/                # Komponen React Native
│   ├── Header.tsx            # Header component
│   ├── BalanceCard.tsx       # Balance display
│   ├── TransactionForm.tsx  # Input form
│   └── TransactionList.tsx  # Transaction list
├── hooks/                     # Custom hooks
│   └── useTransactions.ts   # Data management hook
├── types/                     # TypeScript types
│   └── index.ts             # Transaction interface
├── utils/                     # Utility functions
│   └── helpers.ts          # Helper functions
├── constants/                 # Konstanta
│   └── theme.ts            # Colors & fonts
├── package.json
└── LEARNING_MATERIALS.md

Daftar Commit Pembelajaran

Fase 1: Setup & Types (Commit 1-3)

Commit 1: Setup Project

Topik: Install dependencies, TypeScript interfaces

Materi yang dipelajari:

  • Cara install package dengan npm
  • TypeScript interface untuk mendefinisikan bentuk data
  • Export/import module

Code penting:

// types/index.ts
export interface Transaction {
  id: string;
  amount: number;
  description: string;
  type: 'income' | 'expense';
  category: string;
  date: string;
}

Poin pembelajaran:

  • Interface adalah "blueprint" untuk object
  • Tipe data yang tersedia: string, number, boolean

Commit 2: Theme Constants

Topik: Konstanta warna dan font

Materi yang dipelajari:

  • Mendefinisikan konstanta di React Native
  • Konfigurasi tema aplikasi

Code penting:

// constants/theme.ts
export const COLORS = {
  income: '#4CAF50',
  expense: '#F44336',
  background: '#F5F5F5',
  card: '#FFFFFF',
  text: '#333333',
  primary: '#2196F3',
} as const;

Poin pembelajaran:

  • as const membuat object jadi readonly
  • Gunakan konsistensi warna di seluruh app

Commit 3: Helper Functions

Topik: Fungsi utility

Materi yang dipelajari:

  • Membuat fungsi helper yang reusable
  • Formatting angka dan tanggal
  • Array reduce untuk kalkulasi

Code penting:

// utils/helpers.ts
export const formatRupiah = (amount: number): string => {
  return new Intl.NumberFormat('id-ID', {
    style: 'currency',
    currency: 'IDR',
  }).format(amount);
};

export const calculateBalance = (transactions: Transaction[]): BalanceInfo => {
  const income = transactions
    .filter((t) => t.type === 'income')
    .reduce((sum, t) => sum + t.amount, 0);
  // ...
};

Poin pembelajaran:

  • Intl.NumberFormat untuk mata uang Indonesia
  • reduce untuk menjumlahkan array
  • filter untuk menyaring array

Fase 2: Components (Commit 4-7)

Commit 4: Header Component

Topik: Komponen Pertama

Materi yang dipelajari:

  • Cara membuat komponen React Native
  • View, Text, StyleSheet
  • Interface props

Code penting:

// components/Header.tsx
interface HeaderProps {
  title: string;
}

export const Header: React.FC<HeaderProps> = ({ title }) => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>{title}</Text>
    </View>
  );
};

Poin pembelajaran:

  • Komponen adalah fungsi yang return JSX
  • Props digunakan untuk data dinamis
  • React.FC adalah type untuk functional component

Commit 5: BalanceCard Component

Topik: Props dan conditional styling

Materi yang dipelajari:

  • Menerima object sebagai props
  • Conditional styling (warna berbeda untuk income/expense)

Code penting:

interface BalanceCardProps {
  balance: BalanceInfo;
}

export const BalanceCard: React.FC<BalanceCardProps> = ({ balance }) => {
  return (
    <View>
      <Text style={[styles.amount, styles.income]}>
        +{formatRupiah(balance.income)}
      </Text>
    </View>
  );
};

Poin pembelajaran:

  • Destructure props dengan { balance }
  • Conditional class dengan array [styles.base, isActive && styles.active]

Commit 6: TransactionForm Component

Topik: Form input dengan useState

Materi yang dipelajari:

  • useState untuk form inputs
  • TextInput component
  • TouchableOpacity untuk button
  • ScrollView horizontal

Code penting:

// components/TransactionForm.tsx
const [amount, setAmount] = useState('');
const [description, setDescription] = useState('');
const [type, setType] = useState<'income' | 'expense'>('expense');

<TextInput
  style={styles.input}
  placeholder="Jumlah (Rp)"
  value={amount}
  onChangeText={setAmount}
  keyboardType="numeric"
/>

<TouchableOpacity onPress={() => setType('expense')}>
  <Text>Pengeluaran</Text>
</TouchableOpacity>

Poin pembelajaran:

  • useState menyimpan state komponen
  • onChangeText menangkap input teks
  • keyboardType="numeric" untuk number only
  • TouchableOpacity = button yang bisa ditekan

Commit 7: TransactionList Component

Topik: FlatList dan rendering

Materi yang dipelajari:

  • FlatList untuk list panjang
  • renderItem function
  • Empty state handling

Code penting:

// components/TransactionList.tsx
<FlatList
  data={transactions}
  keyExtractor={(item) => item.id}
  renderItem={renderItem}
  scrollEnabled={false}
/>

if (transactions.length === 0) {
  return <View style={styles.empty}>...</View>;
}

Poin pembelajaran:

  • FlatList lebih efficient dari map
  • keyExtractor untuk key unik
  • renderItem menerima object { item }

Fase 3: State Management (Commit 8-10)

Commit 8: useTransactions Hook

Topik: Custom hooks

Materi yang dipelajari:

  • Membuat custom hook
  • useState dan useEffect
  • Load data dari AsyncStorage

Code penting:

// hooks/useTransactions.ts
export const useTransactions = () => {
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [loading, setLoading] = useState(true);

  const loadTransactions = async () => {
    const stored = await AsyncStorage.getItem(STORAGE_KEY);
    if (stored) setTransactions(JSON.parse(stored));
  };

  useEffect(() => {
    loadTransactions();
  }, []);

  return { transactions, loading };
};

Poin pembelajaran:

  • Hook adalah fungsi dengan "use" prefix
  • useEffect untuk side effects (API calls)
  • AsyncStorage untuk persistence lokal

Commit 9: addTransaction

Topik: State update dengan callback

Materi yang dipelajari:

  • Menambah item ke state
  • Callback function
  • useCallback untuk optimisasi

Code penting:

const addTransaction = useCallback((transaction: Transaction) => {
  setTransactions((prev) => {
    const updated = [transaction, ...prev];
    AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
    return updated;
  });
}, []);

Poin pembelajaran:

  • Gunakan functional update setTransactions(prev => ...)
  • Selalu simpan ke storage setelah update

Commit 10: deleteTransaction

Topik: Hapus item dari state

Materi yang dipelajari:

  • Filter untuk hapus item
  • Update berdasarkan id

Code penting:

const deleteTransaction = useCallback((id: string) => {
  setTransactions((prev) => {
    const updated = prev.filter((t) => t.id !== id);
    AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
    return updated;
  });
}, []);

Poin pembelajaran:

  • filter mengembalikan array baru (tidak mutate)
  • Compare dengan !== untuk hapus berdasarkan id

Fase 4: Screen Integration (Commit 11-15)

Commit 11: HomeScreen

Topik: Menggabungkan komponen

Materi yang dipelajari:

  • Import dan gunakan komponen
  • Loading state
  • ScrollView

Code penting:

// screens/HomeScreen.tsx
export default function HomeScreen() {
  const { transactions, loading, addTransaction, deleteTransaction } = useTransactions();
  const balance = calculateBalance(transactions);

  if (loading) {
    return <ActivityIndicator />;
  }

  return (
    <View>
      <Header title="Pengeluaran Kita" />
      <ScrollView>
        <BalanceCard balance={balance} />
        <TransactionForm onAdd={addTransaction} />
        <TransactionList transactions={transactions} onDelete={deleteTransaction} />
      </ScrollView>
    </View>
  );
}

Poin pembelajaran:

  • Custom hook return multiple values dengan destructuring
  • ActivityIndicator untuk loading state
  • ScrollView untuk konten panjang

Commit 12-15: App Integration

Topik: Expo Router & Navigation

Materi yang dipelajari:

  • File-based routing dengan expo-router
  • Tab navigation
  • Layout configuration

Fase 5: Enhancements (Commit 16-21)

Topics tambahan:

  • Categories management
  • Form validation
  • Code refactoring

Cara Menggunakan untuk Pembelajaran

Cara 1: Ikuti Commit Satu per Satu

  1. Clone repository:

    git clone <repo-url>
    cd duit
    
  2. Lihat semua commits:

    git log --oneline
    
  3. Pergi ke commit tertentu:

    git checkout <commit-hash>
    
  4. Install dan run:

    npm install
    npx expo start
    

Cara 2: Belajar dari Kode

  1. Clone repository di commit terakhir
  2. Baca kode di setiap file
  3. Pahami hubungan antar komponen
  4. Modifikasi untuk latihan

Cara 3: Latihan Pengembangan

  1. Di commit terakhir, tambahkan fitur:
    • Filter transaksi per kategori
    • Edit transaksi yang sudah ada
    • Export data ke CSV
    • Dark mode

Cara Run Aplikasi

Di Emulator Android

npx expo start --android

Di Emulator iOS (Mac only)

npx expo start --ios

Di Browser (Web)

npx expo start --web

Di Smartphone

  1. Install "Expo Go" dari App Store/Play Store
  2. Scan QR code dari terminal

Debugging Tips

  1. React Native Debugger

    • iOS: Cmd + D
    • Android: Cmd + M atau Ctrl + M
    • Enable "Debug JS Remotely"
  2. Console.log

    console.log('Data:', transactions);
    
  3. Error Boundary

    • Perhatikan error merah di emulator
    • Check terminal untuk stack trace

Fitur Aplikasi

  • Tambah income/pengeluaran
  • Lihat saldo total
  • Riwayat transaksi
  • Hapus transaksi
  • Kategori transaksi
  • Simpan data lokal (AsyncStorage)
  • Tab navigation (Keuangan & Statistik)
  • Ringkasan bulanan
  • Kategori pengeluaran terbesar

Daftar Commit Lengkap

# Commit Hash Deskripsi
1 feat: setup project and add types Install AsyncStorage, Transaction interface
2 feat: add theme constants COLORS, FONTS
3 feat: add helper utility functions formatRupiah, calculateBalance
4 feat: create Header component Komponen title
5 feat: create BalanceCard component Tampilan saldo
6 feat: create TransactionForm component Form input
7 feat: create TransactionList component List riwayat
8 feat: create useTransactions hook Load data
9 feat: add addTransaction function Tambah transaksi
10 feat: add deleteTransaction function Hapus transaksi
11 feat: create HomeScreen Gabung komponen
12 feat: update index to use HomeScreen Entry point
13 feat: configure tab navigation Tab config
14 feat: create Explore/StatsScreen Statistik
15 feat: simplify root layout Layout utama
16 docs: add learning materials Dokumentasi
17 feat: add CATEGORIES constant Categories array
18 refactor: use CATEGORIES from types Import categories
19 refactor: add getCategoryLabel helper Helper function
20 feat: add form validation Alert, validation

Referensi


Happy Learning! 🚀