Belajar Remix - UI & Component Composition
Episode 6 of 24

Belajar Remix - UI & Component Composition

Episode ini membahas sisi tampilan Remix: membuat komponen React reusable, styling dengan CSS Modules, Tailwind, dan styled-components, interaktivitas client-side, serta cara mengoptimalkan UI yang di-render di server.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Routing dan data sudah kalian kuasai. Sekarang masuk ke bagian yang paling terlihat: UI dan komposisi komponen. Di sinilah kode teknis berubah menjadi pengalaman yang dirasakan pengguna.

Remix adalah React, jadi seluruh kebiasaan komponen React berlaku. Yang membedakan adalah disiplin: karena komponen di-render di server lalu di-hydrate di client, kalian harus sadar kode mana yang jalan di server, di client, atau keduanya. Episode ini mengajarkan kebiasaan itu sejak awal.

Episode 6 akan membahas komponen reusable, tiga pendekatan styling yang umum di ekosistem Remix, interaktivitas client-side, dan cara mengoptimalkan UI yang memang dilahirkan di server.

Komponen React Reusable

Komponen sebagai Fungsi

Komponen adalah fungsi yang menerima props dan mengembalikan elemen UI. Kunci reuse adalah memisahkan bagian yang berulang menjadi komponen kecil dengan tanggung jawab tunggal — misalnya tombol, kartu, atau badge — lalu mengomposisikannya di halaman.

JSKomponen reusable dengan props
export function Kartu({ judul, children }) {
  return (
    <article>
      <h2>{judul}</h2>
      <div>{children}</div>
    </article>
  );
}

Props menentukan perilaku komponen; children memungkinkan komposisi bersarang. Dengan pola ini, halaman hanya menyusun blok, bukan mengulang markup yang sama berkali-kali.

Folder Komponen

Simpan komponen bersama route yang memakainya, atau di folder app/components bila dipakai lintas halaman. Pola ini akan dibahas lebih dalam di episode 18. Untuk sekarang, cukup ingat prinsipnya: satu komponen, satu file, satu tanggung jawab.

Styling di Remix

CSS Modules

Remix mendukung CSS Modules tanpa konfigurasi tambahan. Buat file .module.css, import di komponen, dan Remix menangani scope-nya. Kelas di-scope per komponen sehingga tidak ada tabrakan nama antar file.

CSSFile Button.module.css
.tombol { background: #2563eb; color: white; padding: 8px 16px; }
JSMenggunakan CSS Modules
import styles from "./Button.module.css";
 
export function Tombol() {
  return <button className={styles.tombol}>Klik</button>;
}

Import styles dari .module.css menghasilkan objek yang memetakan nama kelas. Remix bahkan mengoptimalkan CSS dengan mengirim hanya file yang dipakai route tertentu.

Tailwind CSS

Tailwind adalah pilihan paling populer di komunitas Remix. Integrasinya sederhana: install paket Tailwind, jalankan init, dan hubungkan path konten ke folder app. Khususnya di Remix v3 yang berbasis Vite, plugin Tailwind bisa dipasang langsung di vite.config.ts.

styled-components

styled-components dan CSS-in-JS lain juga berfungsi, tetapi ada biaya: CSS baru di-inject setelah hydration, sehingga bisa menyebabkan flash. Jika kalian memilih CSS-in-JS, pertimbangkan pendekatan yang mendukung rendering di server. Untuk aplikasi berbasis konten, CSS Modules dan Tailwind umumnya lebih cocok.

Interaktivitas Client-Side

Event Handler dan State

Meski di-render di server, komponen tetap React penuh setelah hydration. Event handler seperti onClick dan hooks state seperti useState berjalan normal di client. Interaktivitas yang murni lokal — toggle, tab, accordion — tidak perlu loader atau action.

JSInteraktivitas lokal dengan useState
import { useState } from "react";
 
export default function Akordeon({ judul, isi }) {
  const [terbuka, setTerbuka] = useState(false);
  return (
    <div>
      <button onClick={() => setTerbuka(!terbuka)}>{judul}</button>
      {terbuka ? <p>{isi}</p> : null}
    </div>
  );
}

State lokal seperti useState hanya ada di client setelah hydration. UI yang butuh data server tetap memakai loader; interaksi murni visual cukup memakai state lokal.

Kapan Memakai Client Rendering

Gunakan client rendering untuk bagian yang membutuhkan waktu nyata: chat, timer, drag and drop. Selebihnya, biarkan server yang me-render. Prinsip ini menjaga halaman tetap cepat karena JavaScript yang dikirim hanya untuk interaksi yang benar-benar ada.

Optimasi UI Server-Rendered

Mengurangi Beban Client

Karena Remix mengirim HTML yang sudah berisi konten, first paint sangat cepat. Optimasi utama berikutnya adalah mengirim sesedikit mungkin JavaScript. Hindari menulis fetch manual di komponen — itu tugas loader. Gunakan Link prefetch untuk menyiapkan data halaman berikutnya saat hover.

JSPrefetch data saat link di-hover
import { Link } from "@remix-run/react";
 
export default function DaftarArtikel() {
  return <Link prefetch="intent" to="/artikel/1">Baca artikel</Link>;
}

Prop prefetch="intent" meminta Remix me-load data route saat kursor mendekati link. Klik terasa instan karena data sudah siap di cache client.

Audit dengan Lighthouse

Terakhir, biasakan memeriksa hasil kerja dengan Lighthouse di browser. Ukur waktu sampai konten pertama terlihat, jumlah JavaScript yang dikirim, dan skor aksesibilitas. Episode 9 akan membahas optimasi performa lebih dalam, termasuk caching.

Penutup

Episode 6 menutup segitiga UI: komponen reusable yang diorganisir rapi, styling dengan CSS Modules, Tailwind, atau styled-components, interaktivitas client-side yang sadar hydration, dan optimasi agar UI server-rendered tetap ringan di client.

Inti yang harus dibawa pulang:

  • Komponen adalah fungsi yang menerima props; gunakan children untuk komposisi.
  • CSS Modules bekerja tanpa konfigurasi; Tailwind pasang lewat Vite plugin.
  • CSS-in-JS perlu perhatian khusus agar tidak terjadi flash di server render.
  • Interaktivitas lokal cukup memakai state React; data tetap lewat loader.
  • prefetch="intent" menyiapkan data sebelum link diklik.
  • Audit rutin dengan Lighthouse untuk memantau bobot JavaScript dan aksesibilitas.

Di episode 7 selanjutnya kita akan membahas forms dan validation — form handling dengan komponen Form dari Remix, validasi di sisi server dengan feedback di client, rendering error per field, dan progressive enhancement agar form tetap berfungsi tanpa JavaScript. Form adalah tempat Remix benar-benar bersinar.

Belajar Remix - UI & Component Composition | Belajar Remix