React 18 now supports data fetching with Suspense, but many people are still using the old approach. Here's a quick summary:
- Old way: Managing loading with useEffect + useState
- Improved way: Declarative handling with Suspense + fetch or SWR
Example code:
<Suspense fallback={<Loading />}>
<UserProfile userId={id} />
</Suspense>
This way, even if you call fetch directly inside the component, Suspense will automatically handle the loading state.
Note: You should also use ErrorBoundary for error handling. Additionally, to enable concurrent mode, you need to migrate to createRoot.