Skip to content

Commit 4bb86b6

Browse files
committed
Clarify conditional browser rendering example
1 parent 262b84a commit 4bb86b6

1 file changed

Lines changed: 45 additions & 51 deletions

File tree

src/content/reference/react-dom/browser.md

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -236,107 +236,101 @@ export default function SavedDraft() {
236236
237237
### Conditionally rendering in the browser {/*conditionally-rendering-in-the-browser*/}
238238
239-
Like other calls to [`use`](/reference/react/use), you can call `use(browser())` conditionally or inside a custom Hook. For example, a custom Hook can use initial data when it is available during server rendering, and read from IndexedDB in the browser when it isn't:
239+
Like other calls to [`use`](/reference/react/use), you can call `use(browser())` conditionally or inside a custom Hook. For example, a custom Hook can return an initial value when it is provided, and read it from IndexedDB in the browser when it isn't:
240240
241-
```js {3}
242-
function useDraft(draftId, initialDraft) {
243-
if (initialDraft !== undefined) {
244-
return initialDraft;
241+
```js {6}
242+
function useSetting(settingId, initialValue) {
243+
if (initialValue !== undefined) {
244+
return initialValue;
245245
}
246246

247-
use(browser('The draft is stored in IndexedDB.'));
248-
return use(readDraft(draftId));
247+
use(browser('No initial setting was provided.'));
248+
return use(readSetting(settingId));
249249
}
250250
```
251251
252-
On the server, `useDraft` returns `initialDraft` when it is provided. Otherwise, the closest Suspense boundary's fallback remains in the HTML. In the browser, `use(browser())` returns `undefined`, so the Hook continues and reads the draft from IndexedDB.
252+
On the server, `useSetting` returns `initialValue` when it is provided. Otherwise, the closest Suspense boundary's fallback remains in the HTML. In the browser, `use(browser())` returns `undefined`, so the Hook continues and reads the setting from IndexedDB.
253253
254-
This example renders one draft with initial data and one stored in IndexedDB.
255-
256-
Click **Reload** to see the second draft's loading fallback while React reads it from IndexedDB.
254+
In this example, the email notification setting is provided as initial data. The push notification setting is not, so click **Reload** to see its loading fallback while React reads it from IndexedDB.
257255
258256
<Sandpack>
259257
260258
```js src/App.js active
261259
import { Suspense } from 'react';
262-
import { useDraft } from './useDraft.js';
260+
import { useSetting } from './useSetting.js';
263261

264-
function Draft({draftId, title, initialDraft}) {
265-
const draft = useDraft(draftId, initialDraft);
262+
function NotificationSetting({settingId, label, initialValue}) {
263+
const enabled = useSetting(settingId, initialValue);
266264
return (
267265
<li>
268-
<strong>{title}</strong>
269-
<p>{draft}</p>
266+
{label}: <strong>{enabled ? 'On' : 'Off'}</strong>
270267
</li>
271268
);
272269
}
273270

274271
export default function App() {
275272
return (
276273
<>
277-
<h1>Saved drafts</h1>
274+
<h1>Notification settings</h1>
278275
<ul>
279-
<Draft
280-
draftId="release-notes"
281-
title="Release notes"
282-
initialDraft="Announce the next release."
276+
<NotificationSetting
277+
settingId="email"
278+
label="Email notifications"
279+
initialValue={true}
283280
/>
284-
<Suspense fallback={<li>Loading saved draft...</li>}>
285-
<Draft draftId="trip-notes" title="Trip notes" />
281+
<Suspense fallback={<li>Loading push notification setting...</li>}>
282+
<NotificationSetting
283+
settingId="push"
284+
label="Push notifications"
285+
/>
286286
</Suspense>
287287
</ul>
288288
</>
289289
);
290290
}
291291
```
292292
293-
```js src/useDraft.js
293+
```js src/useSetting.js
294294
import { use } from 'react';
295295
import { browser } from 'react-dom';
296-
import { readDraft } from './database.js';
296+
import { readSetting } from './database.js';
297297

298-
export function useDraft(draftId, initialDraft) {
299-
if (initialDraft !== undefined) {
300-
return initialDraft;
298+
export function useSetting(settingId, initialValue) {
299+
if (initialValue !== undefined) {
300+
return initialValue;
301301
}
302302

303-
use(browser('The draft is stored in IndexedDB.'));
304-
return use(readDraft(draftId));
303+
use(browser('No initial setting was provided.'));
304+
return use(readSetting(settingId));
305305
}
306306
```
307307
308308
```js src/database.js hidden
309-
const drafts = {
310-
'trip-notes': 'Remember to pack a charger.',
311-
};
312-
313309
const cache = new Map();
314310

315-
export function readDraft(draftId) {
316-
if (!cache.has(draftId)) {
317-
cache.set(draftId, readDraftFromIndexedDB(draftId));
311+
export function readSetting(settingId) {
312+
if (!cache.has(settingId)) {
313+
cache.set(settingId, readSettingFromIndexedDB(settingId));
318314
}
319-
return cache.get(draftId);
315+
return cache.get(settingId);
320316
}
321317

322-
function readDraftFromIndexedDB(draftId) {
318+
function readSettingFromIndexedDB(settingId) {
323319
return new Promise((resolve, reject) => {
324-
const request = indexedDB.open('browser-example', 1);
320+
const request = indexedDB.open('browser-notification-settings-example', 1);
325321

326322
request.onupgradeneeded = () => {
327-
const store = request.result.createObjectStore('drafts');
328-
for (const [key, value] of Object.entries(drafts)) {
329-
store.add(value, key);
330-
}
323+
const store = request.result.createObjectStore('settings');
324+
store.add(true, 'push');
331325
};
332326

333327
request.onerror = () => reject(request.error);
334328
request.onsuccess = () => {
335-
const transaction = request.result.transaction('drafts');
336-
const draftRequest = transaction.objectStore('drafts').get(draftId);
337-
draftRequest.onerror = () => reject(draftRequest.error);
338-
draftRequest.onsuccess = () => {
339-
setTimeout(() => resolve(draftRequest.result), 600);
329+
const transaction = request.result.transaction('settings');
330+
const settingRequest = transaction.objectStore('settings').get(settingId);
331+
settingRequest.onerror = () => reject(settingRequest.error);
332+
settingRequest.onsuccess = () => {
333+
setTimeout(() => resolve(settingRequest.result), 600);
340334
};
341335
};
342336
});
@@ -350,7 +344,7 @@ export default function Document() {
350344
return (
351345
<html lang="en">
352346
<head>
353-
<title>Saved drafts</title>
347+
<title>Notification settings</title>
354348
<style>{`
355349
h1 { font-size: 24px; margin-top: 0; }
356350
`}</style>
@@ -417,7 +411,7 @@ export async function flushReadableStreamToFrame(readable, frame) {
417411
```css src/styles.css hidden
418412
iframe {
419413
width: 100%;
420-
height: 170px;
414+
height: 240px;
421415
border: 0;
422416
}
423417
```

0 commit comments

Comments
 (0)