Compound Components
Menyusun component terkait yang berbagi state melalui parent pattern agar API UI tetap mudah dibaca di tempat pemakaian.
Tujuan belajar
- Menjelaskan kapan beberapa component layak membentuk satu compound pattern
- Membaca hubungan parent, trigger, dan panel yang berbagi state
- Membangun tabs kecil dengan API yang tetap terlihat jelas di JSX
Isi lesson
5 blok- 1.Saat beberapa bagian selalu bekerja sebagai satu unitBelum selesaiWajib
- 2.Tabs kecil dengan state yang dibagikan melalui contextBelum selesaiWajib
- 3.Context dibatasi pada pola yang membutuhkannyaBelum selesaiWajib
- 4.Coding practiceBelum selesaiWajib
- 5.RingkasanBelum selesaiWajib
Saat beberapa bagian selalu bekerja sebagai satu unit
WajibCompound components adalah beberapa component kecil yang membentuk satu pola UI dan berbagi koordinasi dari parent. Tabs adalah contoh yang mudah: Tabs menyimpan item aktif, TabsList menampung trigger, TabsTrigger meminta perubahan pilihan, dan TabsPanel menampilkan content yang sesuai.
Pola ini berguna ketika beberapa bagian memang selalu memiliki hubungan yang sama, tetapi isi dan susunannya perlu fleksibel di tempat pemakaian. Ia bukan alasan untuk memecah satu component sederhana menjadi banyak file. Mulailah dari pola yang sudah berulang dan memiliki state atau aturan bersama yang nyata.
Bagian ini memengaruhi progres lesson.
Tabs kecil dengan state yang dibagikan melalui context
Wajibimport { createContext, useContext, useState, type ReactNode } from "react";
type TabsContextValue = {
activeValue: string;
setActiveValue: (value: string) => void;
};
const TabsContext = createContext<TabsContextValue | null>(null);
function useTabs() {
const value = useContext(TabsContext);
if (!value) {
throw new Error("Tabs child harus dipakai di dalam Tabs.");
}
return value;
}
function Tabs({ defaultValue, children }: { defaultValue: string; children: ReactNode }) {
const [activeValue, setActiveValue] = useState(defaultValue);
return (
<TabsContext.Provider value={{ activeValue, setActiveValue }}>
<section>{children}</section>
</TabsContext.Provider>
);
}
function TabsList({ children }: { children: ReactNode }) {
return <div role="tablist">{children}</div>;
}
function TabsTrigger({ value, children }: { value: string; children: ReactNode }) {
const { activeValue, setActiveValue } = useTabs();
const isActive = activeValue === value;
return (
<button
id={value}
type="button"
role="tab"
aria-selected={isActive}
aria-controls={value + "-panel"}
onClick={() => setActiveValue(value)}
>
{children}
</button>
);
}
function TabsPanel({ value, children }: { value: string; children: ReactNode }) {
const { activeValue } = useTabs();
if (activeValue !== value) {
return null;
}
return <section id={value + "-panel"} role="tabpanel" aria-labelledby={value}>{children}</section>;
}
export function CourseTabs() {
return (
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="practice">Practice</TabsTrigger>
</TabsList>
<TabsPanel value="overview">Mulai dari tujuan module.</TabsPanel>
<TabsPanel value="practice">Buka practice setelah memahami konsep.</TabsPanel>
</Tabs>
);
}Tabs adalah pemilik state aktif. Child tidak menerima activeValue dari CourseTabs satu per satu; mereka membaca dan mengubah value melalui context yang hanya berlaku di dalam pattern Tabs. Di tempat pemakaian, susunan JSX tetap menunjukkan struktur UI sebenarnya. Pattern ini layak bila trigger dan panel berulang sebagai satu kelompok, bukan untuk dua button yang kebetulan berdampingan sekali.
Bagian ini memengaruhi progres lesson.
Catatan penting
WajibContext dibatasi pada pola yang membutuhkannya
Context di contoh ini bukan global state aplikasi. Ia hanya menjadi jalur koordinasi untuk child Tabs. Batasi context pada API component yang jelas agar consumer dapat memahami component mana yang harus dipakai bersama dan error penggunaan dapat ditemukan lebih awal.
Bagian ini memengaruhi progres lesson.
Coding practice
WajibDibuka di workspace khususBuild course tabs compound pattern
Ubah tabs lokal menjadi compound components yang berbagi active value melalui context kecil di dalam pattern Tabs.
Tujuan awal: Fokus di tab TSX.
Practice ini dibuka di workspace khusus. Buka practice untuk memakai editor, preview, dan cek otomatis.
Tombol selesai aktif setelah semua validasi wajib lolos.
Ringkasan
Wajib- Compound components membantu saat beberapa bagian UI memiliki state dan aturan bersama.
- Parent pattern menyimpan koordinasi; child menjaga API JSX tetap mudah dibaca.
- Context lokal bukan pengganti state management global.
- Berikutnya, kamu akan menggunakan children dan slot-like props untuk fleksibilitas layout tanpa context.
Bagian ini memengaruhi progres lesson.
Langkah berikutnya
Selesaikan bagian penting lesson ini
Lanjutkan blok wajib berikutnya: Saat beberapa bagian selalu bekerja sebagai satu unit.