ReactJS

Belum masuk. Progresmu tidak tersimpan.

Masuk
  • Bab 3 dari 10
  • 30 menit
  • 1 latihan kode
  • 4 soal kuis

JSX dan komponen: aturan menulis UI di JavaScript

Di bab ini (9 bagian)
  1. Tujuan
  2. Apa itu JSX?
  3. JSX dikompilasi jadi apa?
  4. Aturan penulisan JSX
  5. Komponen fungsi
  6. Export dan import komponen
  7. Komposisi: menyusun komponen
  8. Kesalahan umum
  9. Rangkuman

Tujuan bab ini

  • Memahami apa itu JSX dan menjadi apa JSX setelah dikompilasi.
  • Menulis JSX sesuai aturannya: satu root, className, tag tertutup, camelCase, ekspresi dalam {}.
  • Membuat function component dengan nama kapital, lalu meng-export dan meng-import-nya.
  • Menyusun komponen kecil menjadi tampilan besar (komposisi).

Apa itu JSX?

JSX (JavaScript XML) adalah perluasan sintaks JavaScript yang membuat kamu bisa menulis struktur mirip HTML langsung di dalam kode JavaScript.

const nama = "Mujahidin";
const nilai = 92;

const elemen = (
  <div className="kartu">
    <h1>Halo, {nama}!</h1>
    <p>Nilai akhir kamu {nilai}</p>
    <p>Status: {nilai >= 75 ? "Lulus" : "Remedial"}</p>
  </div>
);
// Tampil:
// Halo, Mujahidin!
// Nilai akhir kamu 92
// Status: Lulus

Penting: JSX bukan HTML dan bukan string. Browser tidak mengerti JSX. Saat build, alat seperti Babel atau esbuild (dipakai Vite) mengubah JSX menjadi pemanggilan fungsi JavaScript biasa.

JSX dikompilasi jadi apa?

Di masa lalu, JSX diubah menjadi React.createElement(...). Sejak React 17 ada "JSX transform" baru yang memakai fungsi jsx() dari react/jsx-runtime, dan inilah yang dipakai Vite. Hasilnya sama: sebuah objek yang menggambarkan elemen.

// Yang kamu tulis
<h1 className="judul">Halo, {nama}!</h1>

// Kira-kira hasil kompilasi (gaya lama, lebih mudah dibaca)
React.createElement("h1", { className: "judul" }, "Halo, ", nama, "!");

// Hasilnya objek seperti ini (disederhanakan)
// { type: "h1", props: { className: "judul", children: ["Halo, ", "Mujahidin", "!"] } }

Objek inilah yang menjadi bahan Virtual DOM dari bab sebelumnya. Karena JSX pada akhirnya adalah ekspresi JavaScript, kamu bisa menyimpannya di variabel, mengembalikannya dari fungsi, atau memasukkannya ke array.

Ini juga menjelaskan kenapa nama komponen harus kapital. Saat kompilator melihat <profil /> (huruf kecil), ia membuat createElement("profil") dengan string, dianggap tag HTML. Saat melihat <Profil />, ia membuat createElement(Profil) yang merujuk ke fungsi komponenmu.

Aturan penulisan JSX

1. Satu elemen root

Sebuah ekspresi JSX hanya boleh punya satu elemen terluar, karena satu fungsi tidak bisa mengembalikan dua objek sekaligus. Kalau tidak mau menambah <div> ekstra, pakai Fragment <>...</>.

// Salah: dua elemen sejajar di root
return (
  <h1>Judul</h1>
  <p>Isi</p>
);

// Benar: dibungkus Fragment, tidak menambah elemen ke DOM
return (
  <>
    <h1>Judul</h1>
    <p>Isi</p>
  </>
);

2. className, bukan class

class adalah kata kunci JavaScript, jadi atribut CSS ditulis className. Sama halnya for pada label menjadi htmlFor.

3. Semua tag harus ditutup

Di HTML kamu boleh menulis <br> atau <img src="a.png">. Di JSX semua tag wajib ditutup, termasuk yang tanpa isi: <br />, <img src={url} alt="foto" />, <input type="text" />.

4. Atribut memakai camelCase

Atribut yang terdiri dari beberapa kata ditulis camelCase: onClick, onChange, tabIndex, maxLength. Pengecualian: atribut aria-* dan data-* tetap pakai tanda hubung.

Atribut style menerima objek, bukan string, dan nama properti CSS-nya juga camelCase:

<p style={{ backgroundColor: "black", fontSize: 18 }}>Teks</p>
// Kurung kurawal luar = "masuk mode JavaScript"
// Kurung kurawal dalam = objek style

5. Ekspresi JavaScript di dalam {}

Di dalam {} kamu boleh menaruh ekspresi apa pun: variabel, operasi matematika, pemanggilan fungsi, ternary, atau map.

const harga = 15000;
const jumlah = 3;

<p>Total: Rp{harga * jumlah}</p>          // Total: Rp45000
<p>{"react".toUpperCase()}</p>            // REACT
<img src={user.foto} alt={user.nama} />   // atribut dari variabel

Yang tidak boleh adalah pernyataan (statement) seperti if, for, atau deklarasi const langsung di dalam {}. Kalau butuh percabangan, pakai ternary di dalam JSX atau if di atas return.

Beberapa nilai tidak tampil apa-apa di layar: true, false, null, dan undefined. Angka 0 justru tampil. Ini akan penting di bab rendering bersyarat.

Aturan penulisan JSX

Komponen fungsi

Komponen adalah fungsi JavaScript yang mengembalikan JSX. Itu saja.

function TombolKirim() {
  return <button type="submit">Kirim Data</button>;
}

// Arrow function juga sah
const Judul = () => <h1>Form Kontak</h1>;

Aturannya:

  • Nama diawali huruf kapital. TombolKirim, bukan tombolKirim.
  • Mengembalikan JSX (atau null kalau tidak ingin menampilkan apa-apa).
  • Didefinisikan di level atas file, bukan di dalam komponen lain. Komponen yang dibuat di dalam komponen lain akan dianggap tipe baru setiap render, sehingga isinya terus dibuat ulang dan state-nya hilang.

Export dan import komponen

Biasanya satu komponen disimpan di satu file. Ada dua gaya export:

// src/components/TombolKirim.jsx
export default function TombolKirim() {
  return <button type="submit">Kirim Data</button>;
}

// src/components/Ikon.jsx
export function IkonCek() {
  return <span>✓</span>;
}
export function IkonSilang() {
  return <span>✗</span>;
}
GayaCara exportCara import
Defaultexport default function TombolKirimimport TombolKirim from "./TombolKirim.jsx"
Namedexport function IkonCekimport { IkonCek } from "./Ikon.jsx"

Satu file hanya boleh punya satu default export, tapi boleh banyak named export. Pada default import kamu bebas memberi nama apa pun; pada named import namanya harus sama persis dengan yang di-export.

Komposisi: menyusun komponen

Kekuatan komponen ada di komposisi: komponen kecil dirangkai jadi komponen lebih besar, seperti menyusun LEGO.

// src/App.jsx
import TombolKirim from "./components/TombolKirim.jsx";
import { IkonCek } from "./components/Ikon.jsx";

function FormKontak() {
  return (
    <form>
      <label htmlFor="nama">Nama</label>
      <input id="nama" placeholder="Nama kamu" />
      <TombolKirim />
    </form>
  );
}

export default function App() {
  return (
    <main>
      <h1>Hubungi Kami <IkonCek /></h1>
      <FormKontak />
      <FormKontak />
    </main>
  );
}
// Tampil: judul dengan ikon centang, lalu dua form kontak yang identik

Hasilnya membentuk pohon komponen: App di puncak, di bawahnya FormKontak, dan di dalamnya TombolKirim. Kalau desain tombol berubah, kamu cukup mengedit satu file dan semua form ikut berubah.

Kapan memecah komponen? Patokan praktis: kalau sebuah bagian dipakai lebih dari sekali, atau sebuah komponen sudah terlalu panjang untuk dibaca sekali lihat, pecah jadi komponen baru.

Kesalahan umum

  • Mengembalikan dua elemen sejajar tanpa pembungkus. Bungkus dengan <div> atau Fragment.
  • Menulis class dan for, bukan className dan htmlFor.
  • Lupa menutup tag seperti <img> dan <input>.
  • Nama komponen huruf kecil, sehingga dianggap tag HTML dan tidak dirender.
  • Menaruh if di dalam {}. Pakai ternary atau pindahkan if ke atas return.
  • Salah gaya import: memakai { } untuk default export atau sebaliknya.

Rangkuman

  • JSX adalah sintaks mirip HTML di JavaScript yang dikompilasi menjadi pemanggilan fungsi yang menghasilkan objek elemen.
  • Aturan JSX: satu root (atau Fragment), className, semua tag ditutup, atribut camelCase, ekspresi di dalam {}.
  • Komponen adalah fungsi bernama kapital yang mengembalikan JSX, didefinisikan di level atas file.
  • Default export di-import tanpa kurung kurawal, named export dengan kurung kurawal.
  • Komposisi menyusun komponen kecil menjadi pohon komponen yang mudah dirawat.

Selesaikan bab ini

  1. 1. Baca materi
  2. 2. Latihan kode (1)
  3. 3. Kuis (4 soal)

Latihan kode: Membuat objek elemen seperti hasil JSX

JSX dikompilasi menjadi pemanggilan fungsi yang menghasilkan objek. Tiru prosesnya dengan dua fungsi:

  1. buatElemen(type, props, ...children) mengembalikan objek { type, props }:
    • props adalah salinan baru dari props yang diberikan (null dianggap {}); objek asli tidak boleh diubah.
    • Tanpa children: props tidak punya key children.
    • Satu child: props.children berisi child itu langsung.
    • Lebih dari satu: props.children berisi array.
  2. jenisTag(nama) mengembalikan "komponen" bila huruf pertama nama kapital, dan "html" bila tidak.

Contoh: buatElemen("h1", { className: "judul" }, "Halo, ", "Rina", "!") menghasilkan { type: "h1", props: { className: "judul", children: ["Halo, ", "Rina", "!"] } }, persis bentuk yang kamu tulis sebagai <h1 className="judul">Halo, {nama}!</h1>. Fungsi jenisTag meniru cara kompilator memutuskan apakah <Profil /> merujuk ke komponen atau ke tag HTML.

Cek pemahaman

  1. 1Kenapa JSX memakai className, bukan class?

  2. 2Teks apa yang tampil di layar?

    const harga = 15000;
    const jumlah = 3;
    
    const el = <p>Total: Rp{harga * jumlah}</p>;
  3. 3Menulis <profil /> dengan huruf kecil akan merender komponen Profil buatanmu.

  4. 4File Ikon.jsx berisi export function IkonCek(). Cara import mana yang benar?