You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/reference/rsc/server-components.md
+53-1Lines changed: 53 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -183,7 +183,7 @@ The bundler then combines the data, rendered Server Components and dynamic Clien
183
183
</div>
184
184
```
185
185
186
-
Server Components can be made dynamic by re-fetching them from a server, where they can access the data and render again. This new application architecture combines the simple “request/response” mental model of server-centric Multi-Page Apps with the seamless interactivity of client-centric Single-Page Apps, giving you the best of both worlds.
186
+
Server Components can be made dynamic by re-fetching them from a server, where they can access the data and render again. This new application architecture combines the simple "request/response" mental model of server-centric Multi-Page Apps with the seamless interactivity of client-centric Single-Page Apps, giving you the best of both worlds.
187
187
188
188
### Adding interactivity to Server Components {/*adding-interactivity-to-server-components*/}
189
189
@@ -300,3 +300,55 @@ function Comments({commentsPromise}) {
300
300
The `note` content is important data for the page to render, so we `await` it on the server. The comments are below the fold and lower-priority, so we start the promise on the server, and wait for it on the client with the `use` API. This will Suspend on the client, without blocking the `note` content from rendering.
301
301
302
302
Since async components are not supported on the client, we await the promise with `use`.
303
+
304
+
<Note>
305
+
306
+
#### Alternative: Manual Promise handling in Client Components {/*alternative-manual-promise-handling*/}
307
+
308
+
While the `use()` hook provides seamless integration with Suspense boundaries, you can also handle Promises manually in Client Components using traditional React patterns with `useEffect` and `useState`. This approach gives you more control over loading states and error handling:
309
+
310
+
```js
311
+
// Client Component
312
+
"use client";
313
+
import { useState, useEffect } from'react';
314
+
315
+
functionComments({commentsPromise}) {
316
+
const [comments, setComments] =useState(null);
317
+
const [error, setError] =useState(null);
318
+
319
+
useEffect(() => {
320
+
let cancelled =false;
321
+
322
+
commentsPromise
323
+
.then(data=> {
324
+
if (!cancelled) {
325
+
setComments(data);
326
+
}
327
+
})
328
+
.catch(err=> {
329
+
if (!cancelled) {
330
+
setError(err);
331
+
}
332
+
});
333
+
334
+
return () => {
335
+
cancelled =true;
336
+
};
337
+
}, [commentsPromise]);
338
+
339
+
if (error) return<p>Error loading comments: {error.message}</p>;
- Custom loading indicators without Suspense boundaries
348
+
- Granular error handling at the component level
349
+
- To update parts of the UI progressively as data arrives
350
+
- To maintain existing component patterns while adopting Server Components
351
+
352
+
Both approaches are valid. Choose `use()` for simpler code that works with Suspense, or manual handling when you need more control over the loading experience.
0 commit comments