Mengapa Menggabungkan React & TypeScript?
TypeScript memberikan keamanan tipe (type safety) saat masa kompilasi, mencegah bug runtime secara dini, dan memberikan pengalaman pengembang (Developer Experience) yang sangat baik berkat dukungan autokomplit IDE.
Tip 1: Gunakan ComponentPropsWithoutRef daripada Mendefinisikan Ulang Props HTML
Daripada menuliskan manual properti standar HTML seperti onClick, className, atau disabled, gunakan utilitas bawaan React:
import { ComponentPropsWithoutRef } from 'react';
interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
variant?: 'primary' | 'secondary' | 'danger';
isLoading?: boolean;
}
export function Button({ variant = 'primary', isLoading, children, ...props }: ButtonProps) {
return (
<button disabled={isLoading || props.disabled} className={`btn btn-${variant}`} {...props}>
{isLoading ? 'Memuat...' : children}
</button>
);
}
Tip 2: Manfaatkan Union Types Ketimbang Booleans Serupa
Daripada menggunakan multiple boolean flags yang rawan keadaan konfliktual:
// BAD ❌
interface State {
isLoading: boolean;
isError: boolean;
isSuccess: boolean;
}
// GOOD ✅
type AsyncState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'error'; error: Error }
| { status: 'success'; data: T };
Tip 3: Tipe Generik pada Component Props
Komponen seperti tabel atau dropdown akan jauh lebih fleksibel jika menggunakan TypeScript Generics:
interface SelectProps<T> {
items: T[];
getLabel: (item: T) => string;
onSelect: (item: T) => void;
}
export function Select<T>({ items, getLabel, onSelect }: SelectProps<T>) {
return (
<ul className="select-list">
{items.map((item, index) => (
<li key={index} onClick={() => onSelect(item)}>
{getLabel(item)}
</li>
))}
</ul>
);
}
Kesimpulan
Menerapkan pola-pola ini akan membuat basis kode React Anda jauh lebih kuat, mudah dipelihara saat tim bertambah besar, dan minim kesalahan tak terduga di lingkungan produksi.