Kenapa ini penting
Bayangkan membangun rumah dari satu bongkahan beton raksasa. Mustahil diperbaiki: retak sedikit, semuanya harus dibongkar. Rumah dibangun dari bata, kusen, dan genteng yang terpisah; tiap bagian bisa diganti tanpa mengganggu yang lain. Komponen adalah bata di dunia React. Seluruh aplikasi React, dari tombol kecil sampai halaman penuh, tersusun dari komponen. Kemampuan memecah UI menjadi komponen yang tepat adalah pembeda antara kode React yang rapi dan kode yang sulit dirawat.
Konsep inti
Function component
Komponen React modern adalah fungsi JavaScript yang mengembalikan JSX. Sudah, sesederhana itu. Dulu ada class component, tapi dokumentasi resmi react.dev sekarang mengajarkan function component + hooks, dan semua materi ini mengikuti itu.
function Tombol() {
return <button>Klik aku</button>;
}
Setelah didefinisikan, komponen dipakai seperti tag HTML: <Tombol />.
Nama wajib PascalCase
Nama komponen harus diawali huruf kapital, misalnya Navbar, KartuProduk, DaftarTugas. Ini bukan sekadar gaya: React membedakan tag huruf kecil (<div>, <button>) sebagai elemen HTML bawaan, dan tag huruf besar sebagai komponen buatanmu. Kalau kamu menulis <navbar />, React mengira itu tag HTML bernama navbar yang tidak ada, sehingga komponenmu tidak pernah dipanggil.
Komponen harus murni (pure) saat render
Komponen sebaiknya bertindak seperti fungsi matematika: input sama, output sama. Jangan mengubah variabel di luar komponen atau memanggil API saat render. Efek samping punya tempat sendiri (event handler dan useEffect, dibahas nanti). Inilah kenapa StrictMode merender dua kali: supaya ketidakmurnian cepat terlihat.
Jangan mendefinisikan komponen di dalam komponen lain
Tulis setiap komponen di level teratas file (top-level). Komponen yang didefinisikan di dalam komponen lain akan dibuat ulang di setiap render, sehingga state di dalamnya ter-reset dan performa menurun.
Cara memecah UI menjadi komponen
Langkah praktis yang disarankan dokumentasi React ("Thinking in React"):
- Gambar atau lihat desain UI.
- Beri kotak di setiap bagian yang punya tanggung jawab sendiri.
- Satu komponen idealnya mengerjakan satu hal. Kalau ia membesar, pecah lagi.
- Susun jadi hierarki: komponen induk berisi komponen anak.
Contoh halaman toko kopi:
App
├── Header
│ ├── Logo
│ └── Navigasi
├── DaftarProduk
│ └── KartuProduk (diulang untuk setiap produk)
└── Footer
Tanda sebuah bagian layak menjadi komponen: dipakai berulang (kartu produk), cukup besar untuk punya nama sendiri (header), atau punya logika sendiri (form login).
Export dan import
Satu file biasanya berisi satu komponen utama. Ada dua jenis export:
| Jenis | Cara export | Cara import | Aturan |
|---|---|---|---|
| Default | export default function Header() {} |
import Header from './Header.jsx' |
Satu per file; nama saat import bebas |
| Named | export function Logo() {} |
import { Logo } from './Logo.jsx' |
Boleh banyak per file; nama harus sama persis |
Konvensi umum: satu file satu komponen dengan default export, dan nama file sama dengan nama komponen (Header.jsx berisi Header). Ekstensi .jsx dipakai untuk file yang berisi JSX.
Struktur folder sederhana yang rapi:
src/
├── App.jsx
├── main.jsx
└── components/
├── Header.jsx
├── Footer.jsx
└── KartuProduk.jsx
Contoh kode
Pecah halaman toko kopi menjadi beberapa file:
// src/components/Header.jsx
export function Logo() {
return <strong className="logo">☕ Kopi Nusantara</strong>;
}
export default function Header() {
return (
<header className="header">
<Logo />
<nav>
<a href="#menu">Menu</a> | <a href="#kontak">Kontak</a>
</nav>
</header>
);
}
// src/components/KartuProduk.jsx
export default function KartuProduk() {
return (
<article className="kartu">
<h3>Kopi Toraja</h3>
<p>Rp 90.000</p>
<button>Tambah</button>
</article>
);
}
// src/components/Footer.jsx
export default function Footer() {
const tahun = new Date().getFullYear();
return <footer>© {tahun} Kopi Nusantara</footer>;
}
// src/App.jsx, merakit semua komponen
import Header from './components/Header.jsx';
import KartuProduk from './components/KartuProduk.jsx';
import Footer from './components/Footer.jsx';
export default function App() {
return (
<>
<Header />
<main id="menu">
<h2>Menu Hari Ini</h2>
{/* Komponen yang sama bisa dipakai berulang */}
<KartuProduk />
<KartuProduk />
<KartuProduk />
</main>
<Footer />
</>
);
}
// → Header dengan logo, tiga kartu "Kopi Toraja", lalu footer "© 2026 Kopi Nusantara"
Ketiga kartu masih identik. Di modul berikutnya kita akan memberi data berbeda ke tiap kartu lewat props.
Contoh yang salah dan benar soal komponen bersarang:
// ❌ SALAH: Tombol didefinisikan di dalam Halaman
export default function Halaman() {
function Tombol() {
return <button>OK</button>;
}
return <Tombol />; // Tombol dibuat ulang setiap Halaman render
}
// ✅ BENAR: definisikan di top-level
function Tombol() {
return <button>OK</button>;
}
export function HalamanBenar() {
return <Tombol />;
}
Kesalahan umum
- Nama komponen huruf kecil.
function kartu()lalu<kartu />tidak akan jalan sebagai komponen. PakaiKartu. - Lupa
return. Fungsi dengan kurung kurawal tanpareturnmenghasilkanundefined, layar kosong. Pastikan adareturn (...). - Salah pasangan import/export. Mengimpor named export tanpa kurung kurawal (
import Logo from ...padahalexport function Logo) menghasilkan error atauundefined. Cocokkan jenisnya. - Komponen raksasa. Satu file 500 baris berisi header, list, form, dan modal sekaligus. Pecah berdasarkan tanggung jawab.
- Mendefinisikan komponen di dalam komponen lain. Pindahkan ke top-level agar state tidak ter-reset.
Latihan
- Mudah, Buat komponen
Salamyang menampilkan "Halo, peserta bootcamp!" lalu pakai tiga kali diApp. - Sedang, Pecah halaman blog sederhana menjadi komponen
Navbar,Artikel, danSidebardi foldercomponents/, lalu rakit diApp.jsx. - Menantang, Buat file
components/Ikon.jsxyang berisi tiga named export (IkonRumah,IkonCari,IkonUser, masing-masing mengembalikan emoji dalamspan) dan satu default exportBarIkonyang memakai ketiganya. Impor keduanya diApp.
Lihat solusi
1.
function Salam() {
return <p>Halo, peserta bootcamp!</p>;
}
export default function App() {
return (
<>
<Salam />
<Salam />
<Salam />
</>
);
}
2.
// src/components/Navbar.jsx
export default function Navbar() {
return <nav>Beranda · Tentang · Kontak</nav>;
}
// src/components/Artikel.jsx
export default function Artikel() {
return (
<article>
<h2>Belajar React dari Nol</h2>
<p>React adalah library untuk membangun UI...</p>
</article>
);
}
// src/components/Sidebar.jsx
export default function Sidebar() {
return <aside>Artikel populer: JSX, Props, State</aside>;
}
// src/App.jsx
import Navbar from './components/Navbar.jsx';
import Artikel from './components/Artikel.jsx';
import Sidebar from './components/Sidebar.jsx';
export default function App() {
return (
<>
<Navbar />
<div className="layout">
<Artikel />
<Sidebar />
</div>
</>
);
}
3.
// src/components/Ikon.jsx
export function IkonRumah() {
return <span aria-label="rumah">🏠</span>;
}
export function IkonCari() {
return <span aria-label="cari">🔍</span>;
}
export function IkonUser() {
return <span aria-label="user">👤</span>;
}
export default function BarIkon() {
return (
<div className="bar-ikon">
<IkonRumah /> <IkonCari /> <IkonUser />
</div>
);
}
// src/App.jsx
import BarIkon, { IkonCari } from './components/Ikon.jsx';
export default function App() {
return (
<>
<BarIkon />
<p>Cari sesuatu? <IkonCari /></p>
</>
);
}
Ringkasan
- Function component adalah fungsi JavaScript yang mengembalikan JSX, dipakai seperti tag:
<Header />. - Nama komponen wajib PascalCase agar React membedakannya dari tag HTML bawaan.
- Pecah UI berdasarkan tanggung jawab: satu komponen idealnya mengerjakan satu hal.
- Default export satu per file (import tanpa
{}), named export boleh banyak (import dengan{}dan nama sama). - Definisikan komponen di top-level dan jaga agar render tetap murni.