TypeScript & React: Pengenalan Dasar
Gabungkan kekuatan React dengan keamanan tipe TypeScript! Pelajari cara setup proyek React + TS menggunakan Vite, dan dasar-dasar memberi tipe pada Props, State (useState), dan Event Handler.
React + TypeScript = Duet Maut Bikin UI Solid! (Pengenalan Dasar)
Udah mulai jago kan sama dasar-dasar TypeScript? Udah bisa ngasih tipe ke variabel, fungsi, dan bahkan bikin "cetakan" objek pake interface
atau type
? Keren! Sekarang, gimana caranya kita bawa semua "kekuatan tipe" ini ke dunia ReactJS biar komponen-komponen kita jadi lebih aman, gampang di-debug, dan enak di-maintain?
Menggabungkan React dengan TypeScript itu udah jadi praktik yang umum banget di proyek-proyek React modern, terutama yang skala besar atau dikerjain tim. Kenapa? Karena TypeScript ngebantu banget ngurangin bug yang terkait sama tipe data dan bikin kode jadi lebih jelas.
Di bagian ini, kita bakal kenalan sama dasar-dasar gimana cara pake TypeScript di komponen React, mulai dari setup proyeknya, ngasih tipe ke props, state, sampe event handler.
1. Setup Proyek React dengan TypeScript (Pake Vite, Tentu Saja!)
Sama kayak pas kita bikin proyek React biasa, Vite juga ngasih cara super gampang buat bikin proyek React yang udah langsung terintegrasi sama TypeScript.
-
Perintah di Terminal: Buka terminalmu, navigasi ke folder tempat kamu mau nyimpen proyek, terus jalanin:
bash npm create vite@latest nama-proyek-react-ts -- --template react-ts
Atau kalau pake yarn:
bash yarn create vite nama-proyek-react-ts --template react-ts
- Ganti
nama-proyek-react-ts
dengan nama proyekmu. - Opsi
--template react-ts
itu yang ngasih tau Vite buat pake template React dengan TypeScript.
- Ganti
-
Apa yang Beda?
- Struktur foldernya mirip sama proyek Vite + React biasa, tapi file-file komponen utama (kayak
App
danmain
) sekarang bakal punya ekstensi.tsx
(TypeScript XML) bukan.jsx
. Ekstensi.tsx
ini ngasih tau kalau file itu isinya JSX DAN kode TypeScript. - Udah otomatis ada file
tsconfig.json
yang dikonfigurasi buat React. - Dependensi
typescript
dan@types/react
,@types/react-dom
(file definisi tipe buat React) biasanya juga udah otomatis keinstal dipackage.json
.
- Struktur foldernya mirip sama proyek Vite + React biasa, tapi file-file komponen utama (kayak
Setelah proyek kebuat, jangan lupa cd nama-proyek-react-ts
terus npm install
(atau yarn install
) dan npm run dev
(atau yarn dev
) buat ngejalaninnya!
2. Memberi Tipe pada Props Komponen
Ini salah satu tempat di mana TypeScript bersinar banget di React. Kita bisa ngedefinisiin dengan jelas "kontrak" props yang diterima sebuah komponen.
- Cara Umum: Pake
interface
atautype
alias buat ngedefinisiin bentuk (shape) objek props. - React.FC (Functional Component type - Opsional): Dulu, sering dipake
React.FC<NamaPropsInterface>
sebagai tipe buat functional component.React.FC
ini otomatis nambahinprops.children
ke tipe props. Tapi, sekarang banyak developer yang lebih milih gak pakeReact.FC
dan ngedefinisiin tipe props secara eksplisit aja, karenaReact.FC
punya beberapa perilaku implisit yang kadang kurang disukai (misal,children
jadi opsional otomatis).
Contoh Tanpa React.FC
(Cara yang Makin Populer):
// File: Tombol.tsx
import React from 'react'; // Di proyek Vite modern, import React kadang opsional buat JSX
// 1. Definisikan bentuk props pake interface atau type
interface TombolProps {
teks: string; // Prop 'teks' wajib string
onClick: () => void; // Prop 'onClick' wajib fungsi tanpa argumen & return
disabled?: boolean; // Prop 'disabled' opsional boolean
jenis?: "primer" | "sekunder"; // Prop 'jenis' opsional, nilainya cuma boleh "primer" atau "sekunder" (Union Type)
}
// 2. Kasih tipe ke parameter props di fungsi komponen
function Tombol({ teks, onClick, disabled = false, jenis = "primer" }: TombolProps) {
// Kita pake destructuring props di sini dan kasih nilai default
let kelasDasar = "py-2 px-4 rounded font-semibold transition-colors ";
if (jenis === "primer") {
kelasDasar += "bg-blue-500 text-white hover:bg-blue-600";
} else {
kelasDasar += "bg-gray-200 text-gray-800 hover:bg-gray-300";
}
if (disabled) {
kelasDasar += " opacity-50 cursor-not-allowed";
}
return (
<button className={kelasDasar} onClick={onClick} disabled={disabled}>
{teks}
</button>
);
}
export default Tombol;
// Cara pakenya di komponen lain (misal, App.tsx):
// import Tombol from './Tombol';
// ...
// <Tombol teks="Kirim" onClick={() => console.log('Kirim diklik!')} jenis="primer" />
// <Tombol teks="Batal" onClick={() => console.log('Batal!')} jenis="sekunder" disabled />
// <Tombol teks="Default" onClick={() => {}} /> {/* jenis akan primer, disabled akan false */}
// <Tombol onClick={() => {}} /> // ERROR! Prop 'teks' wajib ada dan belum dikasih.
Dengan TombolProps
, TypeScript bakal ngasih tau kita kalau:
- Kita lupa ngasih prop
teks
atauonClick
. - Kita ngasih tipe yang salah buat prop (misal,
disabled="iya"
padahal harusnya boolean). - Kita ngasih nilai yang gak valid buat prop
jenis
.
Contoh dengan React.FC
(Masih Sering Ditemui):
import React, { FC, ReactNode } from 'react'; // FC adalah Functional Component
interface KartuProps {
judul: string;
children: ReactNode; // children harus didefinisikan kalau mau dipake eksplisit
// React.FC otomatis nambahin children?, tapi lebih baik eksplisit
}
const Kartu: FC<KartuProps> = ({ judul, children }) => {
return (
<div className="border p-4 rounded shadow">
<h2 className="text-xl mb-2">{judul}</h2>
<div>{children}</div>
</div>
);
};
export default Kartu;
Pilihan antara pake React.FC
atau enggak itu seringkali masalah preferensi tim. Tapi, trennya sekarang banyak yang mulai ninggalin React.FC
biar tipe props lebih eksplisit.
3. Memberi Tipe pada State (useState
)
Pas kita pake hook useState
, TypeScript biasanya cukup pinter buat nebak (infer) tipe state-nya dari nilai awal yang kita kasih.
import React, { useState } from 'react';
function Counter() {
const [hitungan, setHitungan] = useState(0); // TS otomatis nebak 'hitungan' itu tipe 'number'
// dan 'setHitungan' itu fungsi (value: number) => void
// hitungan = "nol"; // ERROR! Gak bisa assign string ke number.
// setHitungan("satu"); // ERROR! setHitungan ngarepnya number.
return (
<div>
<p>Hitungan: {hitungan}</p>
<button onClick={() => setHitungan(prev => prev + 1)}>Tambah</button>
</div>
);
}
Tapi, kalau nilai awalnya null
atau undefined
, atau kalau tipe state-nya bisa jadi salah satu dari beberapa tipe (union type), kadang kita perlu ngasih tipe eksplisit ke useState
pake generic type:
import React, { useState } from 'react';
interface Pengguna {
id: number;
nama: string;
}
function ProfilPengguna() {
// State 'user' bisa objek Pengguna atau null (kalau belum login/data belum ada)
// Kita kasih tipe eksplisit: useState<Pengguna | null>(initialValue)
const [user, setUser] = useState<Pengguna | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true); // Eksplisit boolean
// Simulasi fetch data
useEffect(() => {
setTimeout(() => {
setUser({ id: 1, nama: "Budi Reactson" });
setIsLoading(false);
}, 1000);
}, []);
if (isLoading) return <p>Loading...</p>;
if (!user) return <p>Pengguna tidak ditemukan.</p>; // Handle kalau user null
return (
<div>
<h1>{user.nama}</h1> {/* Aman, TS tau user punya properti nama kalau gak null */}
<p>ID: {user.id}</p>
</div>
);
}
Dengan useState<Pengguna | null>(null)
, kita ngasih tau TS kalau user
itu bisa jadi objek Pengguna
atau bisa juga null
.
4. Memberi Tipe pada Event Handler
Pas kita nanganin event di JSX (kayak onClick
, onChange
), fungsi handler kita juga bisa dikasih tipe buat parameternya (objek event
). React nyediain tipe-tipe event sintetik yang bisa kita pake.
React.MouseEvent<T>
: Buat event mouse (misal,onClick
dibutton
).T
itu tipe elemen HTML-nya (misal,HTMLButtonElement
).React.ChangeEvent<T>
: Buat eventonChange
(misal, diinput
,select
,textarea
).T
itu tipe elemen HTML-nya.React.FormEvent<T>
: Buat eventonSubmit
di<form>
.T
itu tipe elemenHTMLFormElement
.- Dan banyak lagi (KeyboardEvent, FocusEvent, dll.).
Contoh:
import React, { useState, ChangeEvent, FormEvent } from 'react';
function FormLogin() {
const [email, setEmail] = useState('');
const handleEmailChange = (event: ChangeEvent<HTMLInputElement>) => {
// 'event.target' otomatis punya tipe HTMLInputElement, jadi 'event.target.value' aman diakses
setEmail(event.target.value);
};
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log("Email yang disubmit:", email);
};
const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
// 'event' di sini punya properti spesifik buat mouse event
console.log("Tombol diklik di koordinat X:", event.clientX);
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={handleEmailChange}
placeholder="Email"
/>
<button type="submit" onClick={handleButtonClick}>Login</button>
</form>
);
}
Dengan ngasih tipe ke objek event
dan elemen targetnya (HTMLInputElement
, HTMLFormElement
), VS Code bisa ngasih auto-completion yang lebih akurat buat properti-properti di event
atau event.target
.
Ini Baru Permulaan!
Apa yang kita bahas ini baru dasar-dasar banget cara pake TypeScript di React. Manfaat TypeScript bakal makin kerasa pas aplikasimu makin gede dan kompleks, apalagi kalau:
- Kamu kerja bareng tim.
- Kamu bikin komponen yang reusable dan mau "kontrak" props-nya jelas.
- Kamu berurusan sama data dari API yang strukturnya udah ditentuin.
Menggabungkan TypeScript sama React itu kayak ngasih "peta" dan "sabuk pengaman" super canggih ke proses development UI-mu. Awalnya mungkin kerasa nambah kerjaan karena harus mikirin tipe, tapi dalam jangka panjang, ini bakal ngirit banyak waktu debugging, bikin kode lebih gampang dipahami, dan kolaborasi jadi lebih enak.
Jangan takut buat nyoba-nyoba ngasih tipe ke semua props, state, dan fungsi di komponen React-mu. VS Code bakal jadi asisten yang super ngebantu di perjalanan ini!
Kuis Dasar TypeScript dengan ReactJS
Pertanyaan 1 dari 5
Saat membuat proyek React baru menggunakan Vite dengan dukungan TypeScript, perintah apa yang biasanya digunakan?