K

Command Palette

Search for a command to run...

Daftar

Studi Kasus To-Do: Setup & Tipe Data

Mulai bangun aplikasi To-Do List dengan React dan TypeScript! Langkah pertama: setup proyek menggunakan Vite dan mendefinisikan interface TypeScript untuk struktur data tugas (Todo).

Proyek To-Do List (React + TS) #1: Siapin Fondasi & "Blueprint" Data!

Waktunya ngoding beneran! Setelah kenalan sama dasar-dasar React dan gimana TypeScript bisa bikin dia makin mantap, sekarang kita bakal langsung praktik ngebangun Aplikasi To-Do List sederhana dari nol.

Di bagian pertama studi kasus ini, kita bakal fokus ke:

  1. Nyiapin proyek React + TypeScript pake Vite (sekalian review singkat).
  2. Ngerancang struktur folder dasar buat komponen-komponen kita.
  3. Yang paling penting buat aspek TypeScript-nya: ngedefinisiin "bentuk" atau tipe data buat satu item tugas (Todo) pake interface.

Ini kayak ngebangun pondasi dan bikin blueprint dulu sebelum mulai nyusun bata-batanya.

Langkah 1: Bikin Proyek React + TypeScript Baru dengan Vite

Kalau kamu belum punya proyek React + TypeScript yang siap, bikin dulu ya! Buka terminalmu dan jalanin:

bash
npm create vite@latest my-todo-app-ts -- --template react-ts

Ganti my-todo-app-ts dengan nama folder proyek yang kamu mau. Setelah selesai, jangan lupa:

bash
cd my-todo-app-ts
npm install 
# atau yarn install jika kamu pake yarn

Dan buat ngejalanin development servernya:

bash
npm run dev
# atau yarn dev

Buka http://localhost:5173/ (atau port yang muncul) di browser. Harusnya kamu liat halaman default Vite + React. Keren!

Langkah 2: Struktur Folder Komponen (Saran)

Biar rapi, kita bakal nyimpen komponen-komponen UI kita di dalem folder src/components/.

  1. Di dalem folder src/ proyekmu, bikin folder baru namanya components.
    • Di VS Code, klik kanan folder src di Explorer > New Folder... > ketik components.

Kita bakal bikin file-file komponen kita (kayak TodoForm.tsx, TodoList.tsx, TodoItem.tsx) di dalem folder components ini nanti.

Langkah 3: Membersihkan App.tsx dan App.css

File src/App.tsx dan src/App.css bawaan Vite itu isinya contoh. Kita bersihin dulu biar bisa mulai dari nol buat aplikasi To-Do kita.

  • Buka src/App.tsx, hapus semua isinya, dan ganti jadi kayak gini dulu:

    tsx
    // src/App.tsx
    import React from 'react'; // Mungkin tidak wajib import React di versi baru dengan Vite
    import './App.css';
     
    function App() {
      return (
        <div className="app-container">
          <h1>Aplikasi To-Do List Saya (React + TS)</h1>
          {/* Komponen-komponen lain bakal kita tambahin di sini nanti */}
        </div>
      );
    }
     
    export default App;
  • Buka src/App.css, hapus semua isinya. Kita bakal isi style-nya nanti.

  • Buka src/index.css, hapus juga semua isinya kalau mau bener-bener mulai dari nol, atau biarin aja kalau mau pake sedikit reset default dari Vite. Buat sekarang, kita bisa hapus aja dulu.

Setelah disimpan, halaman di browser-mu harusnya jadi simpel banget, cuma nampilin judul "Aplikasi To-Do List Saya (React + TS)".

Langkah 4: Mendefinisikan "Bentuk" Data Tugas (Interface Todo)

Ini bagian pentingnya dari sisi TypeScript! Sebelum kita mulai bikin state buat nyimpen daftar tugas, kita perlu definisiin dulu "bentuk" atau struktur data dari satu item tugas (Todo) itu kayak gimana. Properti apa aja yang bakal dimiliki tiap tugas, dan apa tipe datanya?

Kita bakal pake interface buat ini.

  1. Kamu bisa bikin file baru khusus buat nyimpen tipe-tipe data, misalnya src/types.ts (atau src/interfaces.ts). Tapi buat proyek sekecil ini, kita bisa juga definisiin langsung di file yang butuh, misalnya di App.tsx dulu.

    • Untuk sekarang, mari kita bikin di src/App.tsx di bagian atas, sebelum definisi komponen App.
  2. Tambahin kode interface ini:

    typescript
    // src/App.tsx (di bagian atas, sebelum function App)
     
    // Definisikan interface untuk satu item Todo
    export interface Todo {
      id: number;         // ID unik buat tiap todo, tipenya number
      text: string;       // Teks atau deskripsi tugas, tipenya string
      isCompleted: boolean; // Status selesai atau belum, tipenya boolean
    }

    Penjelasan interface Todo:

    • export interface Todo: Kita bikin interface bernama Todo dan kita export biar bisa dipake di file lain kalau perlu (meskipun di contoh ini kita mungkin pakenya di App.tsx aja dulu).
    • id: number;: Tiap todo bakal punya properti id yang tipenya angka. Ini penting buat jadi key pas ngerender list dan buat identifikasi unik.
    • text: string;: Properti text buat nyimpen isi tugasnya, tipenya string.
    • isCompleted: boolean;: Properti isCompleted buat nandain apakah tugasnya udah selesai atau belum, tipenya boolean (true atau false).

Langkah 5: Menggunakan Tipe Todo untuk State Daftar Tugas

Sekarang, kita bisa pake interface Todo yang udah kita bikin tadi buat ngasih tipe ke state todos kita di komponen App.

Ubah bagian useState di src/App.tsx jadi kayak gini:

tsx
// src/App.tsx
import React, { useState, useEffect } from 'react';
import './App.css';
// import TodoForm from './components/TodoForm'; // Nanti kita impor
// import TodoList from './components/TodoList'; // Nanti kita impor
 
// Definisikan interface untuk satu item Todo
export interface Todo {
  id: number;
  text: string;
  isCompleted: boolean;
}
 
function App() {
  // State 'todos' sekarang tipenya adalah array dari objek Todo (Todo[])
  // Nilai awalnya array kosong
  const [todos, setTodos] = useState<Todo[]>(() => { 
    const savedTodos = localStorage.getItem('todos');
    if (savedTodos) {
      try {
        return JSON.parse(savedTodos) as Todo[]; // Type assertion di sini
      } catch (e) {
        console.error("Gagal mem-parse todos dari localStorage:", e);
        return [];
      }
    }
    return [];
  });
 
  useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(todos));
    console.log("Todos disimpan ke localStorage:", todos);
  }, [todos]);
 
  // ... (Fungsi addTodo, toggleComplete, deleteTodo bakal kita isi nanti 
  //      dan harus konsisten sama tipe Todo ini) ...
 
  return (
    <div className="app-container">
      <header>
        <h1>Aplikasi To-Do List Saya (React + TS)</h1>
      </header>
      <main>
        {/* <TodoForm ... /> */}
        {/* <TodoList ... /> */}
        <p>Jumlah tugas saat ini: {todos.length}</p> {/* Cuma buat ngecek */}
      </main>
      <footer>
        <p>Ayo selesaikan semua tugas!</p>
      </footer>
    </div>
  );
}
 
export default App;

Perubahan Penting di useState:

  • useState<Todo[]>(...): Kita ngasih tipe generic Todo[] ke useState. Ini ngasih tau TypeScript kalau state todos itu bakal jadi array yang isinya objek-objek yang bentuknya sesuai sama interface Todo.
  • JSON.parse(savedTodos) as Todo[]: Pas kita ngambil data dari localStorage, JSON.parse() itu ngembaliin tipe any secara default. Kita pake type assertion as Todo[] buat ngasih tau TypeScript, "Hei, aku yakin banget hasil parse ini adalah array Todo ya!". Ini cara buat "maksa" tipe kalau kita udah yakin. (Ada cara lain yang lebih type-safe pake type guard, tapi as cukup buat sekarang).

Manfaatnya Apa? Sekarang, setiap kali kita mau ngoprek state todos (misal, pas nambah todo baru, atau ngedit todo), TypeScript bakal ngecek apakah objek yang kita masukin itu propertinya udah bener sesuai interface Todo. Kalau ada yang salah (misal, id-nya string, atau lupa ngasih isCompleted), TypeScript bakal langsung ngasih tau error! Ini ngebantu banget ngindarin bug tipe data.


Pondasi proyek To-Do List kita udah mulai kebentuk! Kita udah punya proyek React + TS yang jalan, struktur folder dasar, dan yang paling penting, kita udah ngedefinisiin "blueprint" data (interface Todo) yang bakal kita pake.

Dengan interface Todo ini, kerjaan kita selanjutnya (bikin form, nampilin list, nambah, ngubah, hapus tugas) bakal jadi lebih aman dan terstruktur karena TypeScript bakal terus "ngawasin" tipe data kita.

Siap buat mulai bikin komponen form inputnya di materi berikutnya?

Kuis Setup & Tipe Data To-Do List (React+TS)

Pertanyaan 1 dari 5

Saat membuat proyek React baru dengan Vite yang sudah mendukung TypeScript, template apa yang biasanya Anda pilih?