Membangun aplikasi dengan React: konsep components, props, dan state, sintaks JSX, hooks dasar useState dan useEffect, plus apa arti era React Compiler di 2026 — dipraktikkan pada antarmuka reaktif TokoKita

Setelah di episode 5-6 kalian menguasai JavaScript dan TypeScript, sekarang saatnya lompatan besar: React. Di 2026 React adalah library UI paling banyak dipakai, dan fondasi dari meta-framework terpopuler (Next.js, Remix, TanStack Start). Menguasai React berarti menguasai cara berpikir modern tentang UI.
Mengapa tidak terus pakai vanilla JS? Di aplikasi nyata, memanipulasi DOM manual dengan querySelector dan string HTML menjadi tidak terkelola saat ukuran bertambah. React memperkenalkan paradigma yang berbeda: UI adalah fungsi dari state. Kalian mendeskripsikan "bagaimana UI seharusnya terlihat", dan React yang mengurus sinkronisasinya dengan DOM.
Tiga konsep inti React:
| Konsep | Analogi | Penjelasan |
|---|---|---|
| Component | Cetakan/fungsi | Fungsi yang mengembalikan UI, Card(), ProductList() |
| Props | Bahan input | Data yang diteruskan dari induk ke anak, hanya-baca |
| State | Memori komponen | Data yang berubah dan memicu re-render saat berubah |
type ProductCardProps = {
name: string;
price: number;
};
export function ProductCard({ name, price }: ProductCardProps) {
return (
<article className="product-card">
<h2>{name}</h2>
<p>Rp{price.toLocaleString("id-ID")}</p>
</article>
);
}JSX adalah sintaks yang menggabungkan markup dan logika:
export function ProductList({ products }: { products: Product[] }) {
return (
<section className="product-grid">
{products.map((p) => (
<ProductCard key={p.id} name={p.name} price={p.price} />
))}
</section>
);
}Perhatikan: {products.map(...)} menjalankan JavaScript di dalam markup, dan key wajib ada pada list agar React bisa melacak setiap item secara efisien.
Warning
key bukan untuk dekorasi — tanpanya, React bisa salah menempatkan state saat daftar berubah (misal setelah item dihapus). Gunakan id yang stabil, bukan index array, terutama untuk list yang bisa berubah urutannya.
Hooks adalah fungsi bawaan React untuk "mengaitkan" state dan efek pada komponen.
import { useState } from "react";
export function Cart() {
const [items, setItems] = useState<CartItem[]>([]);
const addItem = (item: CartItem) => {
setItems((prev) => [...prev, item]);
};
return (
<button onClick={() => addItem({ productId: 1, quantity: 1 })}>
Tambah ({items.length})
</button>
);
}Pola yang wajib diingat: jangan pernah memutasi state langsung (items.push(...)). Selalu buat nilai baru — [...prev, item] — supaya React tahu terjadi perubahan dan bisa me-render ulang.
useEffect menjalankan efek samping (fetch data, subscribe) setelah render:
useEffect(() => {
fetch("/api/products")
.then((r) => r.json())
.then(setProducts)
.catch(console.error);
}, []);Array dependency [] berarti efek berjalan sekali setelah mount. Hati-hati: di 2026, pola fetch ini umumnya sudah digantikan framework data (episode 9 & 11) — jangan terlalu nyaman dengan useEffect untuk data.
React Compiler (diaktifkan default sejak React 19) secara otomatis melakukan memoization — dulu developer menghafal kapan memakai useMemo dan useCallback untuk performa; sekarang compiler yang melakukannya. Dampak praktisnya:
useMemo di mana-mana.Ini salah satu alasan React tetap relevan di 2026: developer fokus pada logika, bukan mikro-optimasi.
Rangkaian komponen minimal TokoKita:
import { useState } from "react";
import { ProductList } from "./ProductList";
import { Cart } from "./Cart";
const SAMPLE_PRODUCTS: Product[] = [
{ id: 1, name: "Kopi Arabika", price: 85000 },
{ id: 2, name: "Teh Melati", price: 45000 },
];
export function App() {
const [cartCount, setCartCount] = useState(0);
return (
<main id="main">
<h1>Katalog TokoKita</h1>
<p>Keranjang: {cartCount} item</p>
<ProductList products={SAMPLE_PRODUCTS} onAdd={() => setCartCount((c) => c + 1)} />
</main>
);
}Struktur data mengalir satu arah: state di atas (App), data diturunkan sebagai props, event naik lewat callback (onAdd). Ini pola one-way data flow yang membuat alur aplikasi mudah diprediksi.
| Kesalahan | Dampak | Perbaikan |
|---|---|---|
| Mutasi state langsung | Render tidak sinkron | setItems([...prev, item]) |
key pakai index | State salah posisi | key={item.id} |
| Lupa dependency array | Fetch berulang/efek bocor | Isi dependency dengan benar |
| Komponen raksasa | Sulit dirawat | Pecah jadi komponen kecil |
| Menaruh logika di JSX | Sulit dibaca | Pisah fungsi di luar return |
Inti yang harus dibawa pulang:
key wajib untuk list.useState/useEffect; di era React Compiler fokus pada logika, bukan memo manual.Di episode 9 selanjutnya kita membangun di atas React: framework & meta-framework dengan Next.js — App Router, Server Components (RSC), data fetching, dan deployment, sehingga TokoKita menjadi aplikasi full-stack yang siap produksi. Sampai jumpa di episode 9!