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:
- Nyiapin proyek React + TypeScript pake Vite (sekalian review singkat).
- Ngerancang struktur folder dasar buat komponen-komponen kita.
- 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:
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:
cd my-todo-app-ts
npm install
# atau yarn install jika kamu pake yarn
Dan buat ngejalanin development servernya:
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/
.
- Di dalem folder
src/
proyekmu, bikin folder baru namanyacomponents
.- Di VS Code, klik kanan folder
src
di Explorer >New Folder...
> ketikcomponents
.
- Di VS Code, klik kanan folder
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.
-
Kamu bisa bikin file baru khusus buat nyimpen tipe-tipe data, misalnya
src/types.ts
(atausrc/interfaces.ts
). Tapi buat proyek sekecil ini, kita bisa juga definisiin langsung di file yang butuh, misalnya diApp.tsx
dulu.- Untuk sekarang, mari kita bikin di
src/App.tsx
di bagian atas, sebelum definisi komponenApp
.
- Untuk sekarang, mari kita bikin di
-
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 bernamaTodo
dan kitaexport
biar bisa dipake di file lain kalau perlu (meskipun di contoh ini kita mungkin pakenya diApp.tsx
aja dulu).id: number;
: Tiap todo bakal punya propertiid
yang tipenya angka. Ini penting buat jadikey
pas ngerender list dan buat identifikasi unik.text: string;
: Propertitext
buat nyimpen isi tugasnya, tipenya string.isCompleted: boolean;
: PropertiisCompleted
buat nandain apakah tugasnya udah selesai atau belum, tipenya boolean (true
ataufalse
).
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:
// 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 genericTodo[]
keuseState
. Ini ngasih tau TypeScript kalau statetodos
itu bakal jadi array yang isinya objek-objek yang bentuknya sesuai sama interfaceTodo
.JSON.parse(savedTodos) as Todo[]
: Pas kita ngambil data darilocalStorage
,JSON.parse()
itu ngembaliin tipeany
secara default. Kita pake type assertionas Todo[]
buat ngasih tau TypeScript, "Hei, aku yakin banget hasil parse ini adalah arrayTodo
ya!". Ini cara buat "maksa" tipe kalau kita udah yakin. (Ada cara lain yang lebih type-safe pake type guard, tapias
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?