diff --git a/src/components/MDX/Sandpack/template.ts b/src/components/MDX/Sandpack/template.ts index 9ead18a14e4..42f02f6a68e 100644 --- a/src/components/MDX/Sandpack/template.ts +++ b/src/components/MDX/Sandpack/template.ts @@ -28,8 +28,8 @@ root.render( eject: 'react-scripts eject', }, dependencies: { - react: '^18.0.0', - 'react-dom': '^18.0.0', + react: '19.0.0-rc-3edc000d-20240926', + 'react-dom': '19.0.0-rc-3edc000d-20240926', 'react-scripts': '^5.0.0', }, }, diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index b8230f75d3d..b2a7d10bd73 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -309,16 +309,6 @@ li { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - } -} -``` - In this example, `itemsRef` doesn't hold a single DOM node. Instead, it holds a [Map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) from item ID to a DOM node. ([Refs can hold any values!](/learn/referencing-values-with-refs)) The [`ref` callback](/reference/react-dom/components/common#ref-callback) on every list item takes care to update the Map: diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 2beb630aed9..a2bef6bf218 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -572,17 +572,6 @@ export default function App() { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js" -} -``` - @@ -853,8 +842,8 @@ function Throw({error}) { ```json package.json hidden { "dependencies": { - "react": "canary", - "react-dom": "canary", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, @@ -1111,8 +1100,8 @@ function Throw({error}) { ```json package.json hidden { "dependencies": { - "react": "canary", - "react-dom": "canary", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, diff --git a/src/content/reference/react-dom/client/hydrateRoot.md b/src/content/reference/react-dom/client/hydrateRoot.md index b04a239dd40..c54b6fe1159 100644 --- a/src/content/reference/react-dom/client/hydrateRoot.md +++ b/src/content/reference/react-dom/client/hydrateRoot.md @@ -606,17 +606,6 @@ export default function App() { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js" -} -``` - @@ -890,8 +879,8 @@ function Throw({error}) { ```json package.json hidden { "dependencies": { - "react": "canary", - "react-dom": "canary", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, @@ -1152,8 +1141,8 @@ function Throw({error}) { ```json package.json hidden { "dependencies": { - "react": "canary", - "react-dom": "canary", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 39b7ac960e4..047b65aa7eb 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -69,18 +69,6 @@ export default function Search() { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` - ### Handle form submission with a Server Function {/*handle-form-submission-with-a-server-function*/} @@ -170,17 +158,6 @@ export async function submitForm(query) { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` To learn more about the `useFormStatus` Hook see the [reference documentation](/reference/react-dom/hooks/useFormStatus). @@ -250,19 +227,6 @@ export async function deliverMessage(message) { } ``` - -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` - [//]: # 'Uncomment the next line, and delete this line after the `useOptimistic` reference documentatino page is published' @@ -298,8 +262,8 @@ export default function Search() { ```json package.json hidden { "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, @@ -364,18 +328,6 @@ export async function signUpNewUser(newEmail) { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` - Learn more about updating state from a form action with the [`useActionState`](/reference/react/useActionState) docs @@ -412,16 +364,4 @@ export default function Search() { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` - diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index 6e3a908249f..0eb8c5d79d8 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -111,18 +111,6 @@ export async function submitForm(query) { await new Promise((res) => setTimeout(res, 1000)); } ``` - -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` @@ -228,17 +216,6 @@ button { ``` -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` --- diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 8cf723e7f40..5b62794bcf6 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -952,16 +952,6 @@ li { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "beta", - "react-dom": "beta", - "react-scripts": "^5.0.0" - } -} -``` - @@ -1104,16 +1094,6 @@ li { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "beta", - "react-dom": "beta", - "react-scripts": "^5.0.0" - } -} -``` - **With Strict Mode, you immediately see that there is a problem**. Strict Mode runs an extra setup+cleanup cycle for every callback ref. This callback ref has no cleanup logic, so it adds refs but doesn't remove them. This is a hint that you're missing a cleanup function. @@ -1241,16 +1221,6 @@ li { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "beta", - "react-dom": "beta", - "react-scripts": "^5.0.0" - } -} -``` - Now on inital mount in StrictMode, the ref callbacks are all setup, cleaned up, and setup again: diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 7622aa1828b..dc22c907a3a 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -54,21 +54,6 @@ In the example below, the `Albums` component *suspends* while fetching the list -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -114,15 +99,10 @@ function Loading() { } ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -135,31 +115,6 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -254,7 +209,7 @@ async function getAlbums() { - Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) - Lazy-loading component code with [`lazy`](/reference/react/lazy) -- Reading the value of a Promise with [`use`](/reference/react/use) +- Reading the value of a cached Promise with [`use`](/reference/react/use) Suspense **does not** detect when data is fetched inside an Effect or event handler. @@ -285,21 +240,6 @@ In the example below, both `Biography` and `Albums` fetch some data. However, be -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -360,15 +300,10 @@ export default function Panel({ children }) { } ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -377,42 +312,12 @@ export default function Biography({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -425,31 +330,6 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -604,27 +484,12 @@ With this change, displaying the `Biography` doesn't need to "wait" for the `Alb The sequence will be: 1. If `Biography` hasn't loaded yet, `BigSpinner` is shown in place of the entire content area. -1. Once `Biography` finishes loading, `BigSpinner` is replaced by the content. -1. If `Albums` hasn't loaded yet, `AlbumsGlimmer` is shown in place of `Albums` and its parent `Panel`. -1. Finally, once `Albums` finishes loading, it replaces `AlbumsGlimmer`. +2. Once `Biography` finishes loading, `BigSpinner` is replaced by the content. +3. If `Albums` hasn't loaded yet, `AlbumsGlimmer` is shown in place of `Albums` and its parent `Panel`. +4. Finally, once `Albums` finishes loading, it replaces `AlbumsGlimmer`. -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -697,15 +562,10 @@ export default function Panel({ children }) { } ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -714,42 +574,12 @@ export default function Biography({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -762,31 +592,6 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -929,21 +734,6 @@ In this example, the `SearchResults` component suspends while fetching the searc -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState } from 'react'; import SearchResults from './SearchResults.js'; @@ -964,15 +754,10 @@ export default function App() { } ``` -```js src/SearchResults.js hidden +```js src/SearchResults.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function SearchResults({ query }) { if (query === '') { return null; @@ -991,31 +776,6 @@ export default function SearchResults({ query }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -1154,21 +914,6 @@ Enter `"a"` in the example below, wait for the results to load, and then edit th -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; import SearchResults from './SearchResults.js'; @@ -1194,14 +939,9 @@ export default function App() { ``` ```js src/SearchResults.js hidden +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function SearchResults({ query }) { if (query === '') { return null; @@ -1220,31 +960,6 @@ export default function SearchResults({ query }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -1360,21 +1075,6 @@ When a component suspends, the closest parent Suspense boundary switches to show -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState } from 'react'; import IndexPage from './IndexPage.js'; @@ -1479,15 +1179,10 @@ function AlbumsGlimmer() { } ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -1500,42 +1195,12 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -1544,34 +1209,9 @@ export default function Biography({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Panel.js hidden +```js src/Panel.js export default function Panel({ children }) { return (
@@ -1745,21 +1385,6 @@ This tells React that the state transition is not urgent, and it's better to kee -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, startTransition, useState } from 'react'; import IndexPage from './IndexPage.js'; @@ -1866,15 +1491,10 @@ function AlbumsGlimmer() { } ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -1887,42 +1507,12 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -1931,34 +1521,9 @@ export default function Biography({ artistId }) {
); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Panel.js hidden +```js src/Panel.js export default function Panel({ children }) { return (
@@ -2128,21 +1693,6 @@ In the above example, once you click the button, there is no visual indication t -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState, useTransition } from 'react'; import IndexPage from './IndexPage.js'; @@ -2252,15 +1802,10 @@ function AlbumsGlimmer() { } ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -2273,42 +1818,12 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -2317,34 +1832,9 @@ export default function Biography({ artistId }) {
); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Panel.js hidden +```js src/Panel.js export default function Panel({ children }) { return (
diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index bab5b8a0e07..48b21fa6109 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -192,17 +192,6 @@ function Button({ show, children }) { } ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-9377e1010-20230712", - "react-dom": "18.3.0-canary-9377e1010-20230712", - "react-scripts": "^5.0.0" - }, - "main": "/index.js" -} -``` - ### Streaming data from the server to the client {/*streaming-data-from-server-to-client*/} @@ -284,9 +273,6 @@ export default function App() { ``` ```js src/index.js hidden -// TODO: update to import from stable -// react instead of canary once the `use` -// API is in a stable release of React import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -304,16 +290,6 @@ root.render( ); ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-9377e1010-20230712", - "react-dom": "18.3.0-canary-9377e1010-20230712", - "react-scripts": "^5.0.0" - }, - "main": "/index.js" -} -``` @@ -404,9 +380,6 @@ export default function App() { ``` ```js src/index.js hidden -// TODO: update to import from stable -// react instead of canary once the `use` -// API is in a stable release of React import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -424,17 +397,6 @@ root.render( ); ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-9377e1010-20230712", - "react-dom": "18.3.0-canary-9377e1010-20230712", - "react-scripts": "^5.0.0", - "react-error-boundary": "4.0.3" - }, - "main": "/index.js" -} -``` #### Providing an alternative value with `Promise.catch` {/*providing-an-alternative-value-with-promise-catch*/} diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index b90c4b0b951..5b14e22d1e8 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -172,18 +172,6 @@ form button { margin-right: 12px; } ``` - -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` @@ -259,18 +247,6 @@ form button { margin-right: 12px; } ``` - -```json package.json hidden -{ - "dependencies": { - "react": "canary", - "react-dom": "canary", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 86c0c7f55e9..3217f870df6 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -101,21 +101,6 @@ In this example, the `SearchResults` component [suspends](/reference/react/Suspe -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState } from 'react'; import SearchResults from './SearchResults.js'; @@ -136,15 +121,10 @@ export default function App() { } ``` -```js src/SearchResults.js hidden +```js src/SearchResults.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function SearchResults({ query }) { if (query === '') { return null; @@ -163,31 +143,6 @@ export default function SearchResults({ query }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -215,7 +170,7 @@ async function getData(url) { async function getSearchResults(query) { // Add a fake delay to make waiting noticeable. await new Promise(resolve => { - setTimeout(resolve, 500); + setTimeout(resolve, 1000); }); const allAlbums = [{ @@ -315,21 +270,6 @@ Enter `"a"` in the example below, wait for the results to load, and then edit th -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; import SearchResults from './SearchResults.js'; @@ -351,15 +291,10 @@ export default function App() { } ``` -```js src/SearchResults.js hidden +```js src/SearchResults.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function SearchResults({ query }) { if (query === '') { return null; @@ -378,31 +313,6 @@ export default function SearchResults({ query }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -430,7 +340,7 @@ async function getData(url) { async function getSearchResults(query) { // Add a fake delay to make waiting noticeable. await new Promise(resolve => { - setTimeout(resolve, 500); + setTimeout(resolve, 1000); }); const allAlbums = [{ @@ -538,21 +448,6 @@ With this change, as soon as you start typing, the stale result list gets slight -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; import SearchResults from './SearchResults.js'; @@ -580,15 +475,10 @@ export default function App() { } ``` -```js src/SearchResults.js hidden +```js src/SearchResults.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function SearchResults({ query }) { if (query === '') { return null; @@ -607,31 +497,6 @@ export default function SearchResults({ query }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` ```js src/data.js hidden @@ -659,7 +524,7 @@ async function getData(url) { async function getSearchResults(query) { // Add a fake delay to make waiting noticeable. await new Promise(resolve => { - setTimeout(resolve, 500); + setTimeout(resolve, 1000); }); const allAlbums = [{ diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 556e6ae8dff..d191bbb551c 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -123,16 +123,4 @@ export async function deliverMessage(message) { ``` -```json package.json hidden -{ - "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", - "react-scripts": "^5.0.0" - }, - "main": "/index.js", - "devDependencies": {} -} -``` - diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index 4216379d22b..906d2113979 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -1123,21 +1123,6 @@ Here is a tiny simplified router example using Transitions for navigations. -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` - ```js src/App.js import { Suspense, useState, useTransition } from 'react'; import IndexPage from './IndexPage.js'; @@ -1247,15 +1232,10 @@ function AlbumsGlimmer() { } ``` -```js src/Albums.js hidden +```js src/Albums.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -1268,42 +1248,12 @@ export default function Albums({ artistId }) { ); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Biography.js hidden +```js src/Biography.js +import {use} from 'react'; import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. - -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. - export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -1312,34 +1262,9 @@ export default function Biography({ artistId }) {
); } - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} ``` -```js src/Panel.js hidden +```js src/Panel.js export default function Panel({ children }) { return (
@@ -1578,8 +1503,8 @@ root.render( ```json package.json hidden { "dependencies": { - "react": "canary", - "react-dom": "canary", + "react": "19.0.0-rc-3edc000d-20240926", + "react-dom": "19.0.0-rc-3edc000d-20240926", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" },