Reactjs Error Boundaries Suspense Portals Fallback Patterns
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Empat pola ini sering dipakai saat UI React mulai berurusan dengan kegagalan render, data yang belum siap, dan kebutuhan menampilkan elemen di luar hierarki DOM normal.
Keempatnya sering dipakai bersama. Error boundary menjaga aplikasi tetap hidup saat render gagal. Suspense menjaga pengalaman loading tetap rapi. Portal membantu overlay seperti modal dan tooltip tetap berada di layer yang benar. Fallback pattern menjahit semuanya supaya UI tidak terasa putus.
Pilih pola yang sesuai dengan masalahnya, jangan disatukan tanpa alasan.
Pakai saat ada subtree yang bisa gagal render karena data, props, atau kode anaknya sendiri.
Contoh umum:
Pakai saat UI perlu menunggu sesuatu sebelum bagian tertentu ditampilkan.
Contoh umum:
React.lazy()Pakai saat elemen perlu tetap dirender oleh React, tetapi secara visual harus keluar dari nesting normal.
Contoh umum:
Pakai saat UI tidak boleh berhenti hanya karena satu kondisi belum siap.
Contoh fallback yang sehat:
Error Boundary menangkap error pada fase render subtree anak. Ini penting: ia bukan penangkap semua error global.
Error boundary menangkap error yang muncul saat:
Error boundary tidak menangkap secara otomatis:
onClicksetTimeout, promise, atau fetch biasaKalau error terjadi di event handler, tetap perlu try/catch atau penanganan error di layer lain.
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
Suspense mengubah cara kita memikirkan loading. Alih-alih semua loading ditaruh di satu state global, bagian UI bisa punya fallback sendiri.
Saat anak di dalam <Suspense> belum siap, React menahan render bagian itu dan menampilkan fallback.
import { Suspense, lazy } from 'react';
const SettingsPanel = lazy(() => import('./SettingsPanel'));
export default function Page() {
return (
<Suspense fallback={<p>Memuat panel...</
Loading state biasa biasanya eksplisit:
isLoading di stateSuspense lebih cocok saat loading adalah bagian dari mekanisme render, bukan sekadar flag UI.
Praktik yang sehat:
Fallback bukan cuma spinner. Yang bagus adalah fallback yang cocok dengan jenis ketidak-siapan UI.
Pakai untuk konten yang bentuk akhirnya sudah jelas.
Cocok untuk:
Skeleton bagus karena menjaga struktur layout tetap stabil.
Pakai untuk proses singkat atau saat struktur final belum penting.
Cocok untuk:
Jangan dipakai terus-menerus untuk konten panjang karena memberi rasa “menggantung”.
Pakai saat data memang kosong, bukan karena error.
Contoh:
Empty state sebaiknya menjelaskan alasan dan aksi berikutnya.
Pakai saat data gagal diambil atau render gagal di area tertentu.
Minimal berisi:
Pakai saat satu area gagal tetapi area lain masih bisa tampil.
Ini sering lebih baik daripada menjatuhkan seluruh halaman.
Portal membuat React merender subtree ke node DOM lain. Di React, ini sering dipakai untuk overlay yang harus keluar dari flow normal layout.
Pakai portal ketika elemen overlay:
overflow: hiddenimport { createPortal } from 'react-dom';
export default function Modal({ open, children }) {
if (!open) return null;
return createPortal(
<div className=
Portal mengubah posisi DOM output, bukan menghapus hubungan React tree.
Artinya:
Bagian ini sering jadi sumber bug yang kelihatannya “CSS”, padahal akar masalahnya campuran DOM, stacking context, dan event.
Portal biasanya dipakai untuk menghindari layering yang terjebak di parent dengan transform, opacity, position, atau z-index yang menciptakan stacking context baru.
Kalau modal tetap ketutup, cek:
transformoverflow: hiddenModal sering butuh body scroll lock. Kalau hanya overlay yang dipasang tanpa mengunci scroll, user bisa scroll latar belakang saat modal terbuka.
Portal tidak otomatis mengurus aksesibilitas.
Tetap perlu:
aria-modal, role="dialog", dan label yang benarKarena event React mengikuti tree React, klik di dalam portal bisa tetap memicu handler parent React tertentu jika struktur logiknya tidak dipikirkan dengan benar.
Kalau ada modal, dropdown, dan tooltip sekaligus, urutan layer harus didefinisikan. Jangan mengandalkan z-index acak.
Prinsip yang sehat:
Pola-pola ini jarang berdiri sendiri.
Dipakai bersama saat satu subtree bisa gagal sekaligus punya loading async.
Dipakai saat loading state perlu terasa stabil dan tidak loncat layout.
Dipakai saat modal berisi komponen yang bisa gagal. Error boundary di dalam modal bisa mencegah kegagalan menutup seluruh aplikasi.
Dipakai untuk toast, popover, dan modal supaya fallback/loading-nya tetap muncul di atas konten utama.
<ErrorBoundary fallback={<p>Section gagal dimuat.</p>}>
<Suspense fallback={<SkeletonPanel />}>
<DashboardSection />
</Suspense>
</ErrorBoundary>Untuk modal:
<ModalPortal>
<ErrorBoundary fallback={<p>Modal error.</p>}>
<Suspense fallback={<ModalSkeleton />}>
<ModalContent />
</Suspense>
</ErrorBoundary>
</ModalPortalKalau dirancang dengan benar, keempatnya membuat UI React lebih tahan banting tanpa mengorbankan struktur komponen.