Reactjs Suspense For Data Libraries Error Recovery Reset
Definisi
Suspense for Data adalah pola di mana pustaka data (Relay, React Query via useSuspenseQuery, atau use() bawaan) mengintegrasikan diri ke Suspense, sehingga komponen bisa "menunggu" data tanpa useEffect + state loading manual. Error Recovery menunjukkan cara merespons error di dalam boundary dan memulihkan UI tanpa remount seluruh tree.
Kapan dipakai
- Suspense for data: ingin loading state terpusat di
<Suspense fallback>, komponen jadi bersih tanpaisLoadingboilerplate. - Error recovery: saat data gagal, tampilkan fallback lalu beri tombol retry yang me-reset error boundary tanpa reload halaman.
Hindari suspense untuk data yang harus di-cache manual/optimistic; kombinasikan dengan strategi lain bila perlu.
Cara kerja
use() untuk async
import { use } from 'react';
function Profile({ userPromise }: { userPromise: Promise<User> }) {
const user = use(userPromise); // suspend sampai resolve
return <h1>{user.name}</h1>;
}Suspense boundary
<Suspense fallback={<Skeleton />}>
<Profile userPromise={fetchUser()} />
</Suspense>Error boundary + reset
class ErrorBoundary extends React.Component {
state = { error: null };
static getDerivedStateFromError(error: Error) {
return { error };
}
retry = () => this.setState({ error: null });
render() {
if (this.state.error) {
return (
<div>
<p>Gagal memuat.</p>
<button onClick={this.retry}>Coba lagi</button>
</div>
);
}
return this.props.children;
}
}Tombol retry mengubah state boundary sehingga anak dirender ulang dan promise baru dijalankan.
Struktur alur
Loading diagram...
Contoh React Query suspense
const { data } = useSuspenseQuery({ queryKey: ['user'], queryFn: fetchUser });Catatan implementasi
- Promise harus dibuat di luar render atau di-cache, kalau tidak tiap render bikin promise baru dan suspend selamanya.
- Error boundary harus class component (belum ada hook boundary resmi), atau pakai library seperti
react-error-boundary. use()hanya boleh dipakai di client component (RSC tidak punya suspense data bawaan yang sama).
Kesalahan umum
- Promise baru tiap render:
use(fetchUser())di dalam komponen menyebabkan loop suspend. - Tanpa error boundary: error data langsung merusak seluruh halaman.
- Retry tidak reset: klik retry tapi promise lama dipakai lagi, tetap gagal.
- Nested suspense berlebih: terlalu banyak boundary membuat UX terasa patah-patah.