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/blog/2024/04/01/react-19.md
+92-95Lines changed: 92 additions & 95 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -107,13 +107,13 @@ The async transition will immediately set the `isPending` state to true, make th
107
107
Actions automatically manage submitting data for you:
108
108
109
109
-**Pending state**: Actions provide a pending state that starts at the beginning of a request and automatically resets when the final state update is committed.
110
-
-**Optimistic updates**: Actions support the new [`useOptimistic`](#new-feature-optimistic-updates) hook to handle optimistically showing the user the final state while requests are submitting.
111
-
-**Error Handling**: Actions provide error handling so you can and display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically.
112
-
-**Forms**: Actions support new `action`prop for `<form>`elements called [Form Actions](#form-actions). This means form submissions use Actions by default, and reset automatically after submission.
110
+
-**Optimistic updates**: Actions support the new [`useOptimistic`](#new-feature-optimistic-updates) hook so you can show users instant feedback while the requests are submitting.
111
+
-**Error handling**: Actions provide error handling so you can and display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically.
112
+
-**Forms**: Actions integrate with new `action`and `formActions` props as [`<form>` Actions](#form-actions). This means form submissions use Actions by default and reset the form automatically after submission.
113
113
114
114
</Note>
115
115
116
-
Async transitions are the raw primitive that power Actions, and you can always drop down to `useTransition`, `useState`, and `useOptimisitc` to create your own custom behavior. We're also introducing the [`useActionState`](#new-hook-useactionstate) and [`useFormStatus`](#new-hook-useformstatus) hooks to support the common cases for Actions and Forms.
116
+
Async transitions are the raw primitive that power Actions, and you can always drop down to `useTransition`, `useState`, and `useOptimistic` to create your own custom behavior. We're also introducing the [`useActionState`](#new-hook-useactionstate) and [`useFormStatus`](#new-hook-useformstatus) hooks to support the common cases for Actions and Forms.
117
117
118
118
For more information, see the docs for [`useTransition`](/reference/react/useTransition) and the next sections.
119
119
@@ -123,7 +123,7 @@ To make the common cases easier for Actions, we've added a new hook called `useA
@@ -145,13 +145,13 @@ See [#28491](https://github.com/facebook/react/pull/28491) for more info.
145
145
146
146
For more information, see the docs for [`useActionState`](/reference/react/useActionState).
147
147
148
-
### Form Actions {/*form-actions*/}
148
+
### `<form>` Actions {/*form-actions*/}
149
149
150
-
Actions are also integrated with React 19's new Form features. We've added an `action`prop to React DOM `<form>` elements to automatically submit forms with Actions:
150
+
Actions are also integrated with React 19's new `<form>` features. We've added `action`and `formAction` props to React DOM `<form>`, `<input>`, and `<button>` elements to automatically submit forms with Actions:
When a `<form>` Action succeeds, React will automatically reset the form for uncontrolled components. If you need to reset the `<form>` manually, you can call the new [`requestFormReset`](/todo) React DOM API.
166
166
167
+
For more information, see the docs for [`<form>`](/reference/react-dom/components/form), [`<input>`](/reference/react-dom/components/input), and [`<button>`](/reference/react-dom/components/button).
168
+
167
169
### New Hook: `useFormStatus` {/*new-hook-useformstatus*/}
168
170
169
-
In design systems, it's common to write design components that need access to the nearest Form status, without passing the status down to the component. This can be done via Context, but to make the common case easier, we've added a new hook `useFormStatus`:
171
+
In design systems, it's common to write design components that need access to information about the `<form>` they're in, without drilling props down to the component. This can be done via Context, but to make the common case easier, we've added a new hook `useFormStatus`:
`useFormStatus`works like Context for the nearest`<form>`element, returning its `pending` state, the last submitted form `data`, and the `action`.
180
+
`useFormStatus`reads the status of the parent`<form>`as if the form was a Context provider.
184
181
185
182
For more information, see the docs for [`useFormStatus`](/reference/react-dom/hooks/useFormStatus).
186
183
@@ -332,6 +329,76 @@ Todo: This requires the new transform, correct?
332
329
333
330
For more information, see [Manipulating the DOM with refs](/learn/manipulating-the-dom-with-refs)
334
331
332
+
### Diffs for Hydration Errors {/*diffs-for-hydration-errors*/}
333
+
334
+
We also improved error reporting for hydration errors. For example, instead of logging multiple errors in DEV without any information about the mismatch:
335
+
336
+
<ConsoleBlockMulti>
337
+
338
+
<ConsoleLogLinelevel="error">
339
+
340
+
Warning: Text content did not match. Server: "Server" Client: "Client"
341
+
{' '}at span
342
+
{' '}at App
343
+
344
+
</ConsoleLogLine>
345
+
346
+
<ConsoleLogLinelevel="error">
347
+
348
+
Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div\>.
349
+
350
+
</ConsoleLogLine>
351
+
352
+
<ConsoleLogLinelevel="error">
353
+
354
+
Warning: Text content did not match. Server: "Server" Client: "Client"
355
+
{' '}at span
356
+
{' '}at App
357
+
358
+
</ConsoleLogLine>
359
+
360
+
<ConsoleLogLinelevel="error">
361
+
362
+
Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div\>.
363
+
364
+
</ConsoleLogLine>
365
+
366
+
<ConsoleLogLinelevel="error">
367
+
368
+
Uncaught Error: Text content does not match server-rendered HTML.
369
+
{' '}at checkForUnmatchedText
370
+
{' '}...
371
+
372
+
</ConsoleLogLine>
373
+
374
+
</ConsoleBlockMulti>
375
+
376
+
We now log a single message with a diff of the mismatch:
377
+
378
+
379
+
<ConsoleBlockMulti>
380
+
381
+
<ConsoleLogLinelevel="error">
382
+
383
+
Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if an SSR-ed Client Component used:{'\n'}
384
+
\- A server/client branch `if (typeof window !== 'undefined')`.
385
+
\- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
386
+
\- Date formatting in a user's locale which doesn't match the server.
387
+
\- External changing data without sending a snapshot of it along with the HTML.
388
+
\- Invalid HTML tag nesting.{'\n'}
389
+
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.{'\n'}
390
+
https://react.dev/link/hydration-mismatch {'\n'}
391
+
{' '}\<App\>
392
+
{' '}\<span\>
393
+
{'+ '}Client
394
+
{'- '}Server{'\n'}
395
+
{' '}at throwOnHydrationMismatch
396
+
{' '}...
397
+
398
+
</ConsoleLogLine>
399
+
400
+
</ConsoleBlockMulti>
401
+
335
402
### `<Context>` as a provider {/*context-as-a-provider*/}
336
403
337
404
In React 19, you can render `<Context>` as a provider instead of `<Context.Provider>`:
@@ -377,7 +444,7 @@ When the component unmounts, React will call the cleanup function returned from
377
444
378
445
<Note>
379
446
380
-
Previously, React would call ref functions with `null` when unmounting the component. If your ref returns a cleanup function, React will skip this step.
447
+
Previously, React would call ref functions with `null` when unmounting the component. If your ref returns a cleanup function, React will now skip this step.
381
448
382
449
In future versions, we will deprecate calling the ref with `null` when unmounting components.
383
450
@@ -414,11 +481,11 @@ In React 19, we're adding support for rendering document metadata tags in compon
414
481
```js {5,6}
415
482
function BlogPost({post}) {
416
483
return (
417
-
<div>
418
-
<p>{post.title}</p>
484
+
<article>
485
+
<h1>{post.title}</h1>
419
486
<title>{post.title}</title>
420
487
<meta name="keywords" content={post.keywords} />
421
-
</div>
488
+
</article>
422
489
);
423
490
}
424
491
```
@@ -446,9 +513,9 @@ return (
446
513
```
447
514
When React renders this component, it will see the `<link>`, `<style>`, and `<script>` tags and hoist them to the `<head>` of the document.
448
515
449
-
For some resource elements, React will suspend while waiting for the resource to load (such as a `<link>` to a css file). This ensures that styles are available before the components are displayed, preventing flashes of un-styled content. React may also dedupe some elements to ensure duplicate resources are not loaded.
516
+
For some resource elements, React will suspend while waiting for the resource to load (such as a `<link>` to a CSS file). This ensures that styles are available before the components are displayed, preventing flashes of un-styled content. React may also dedupe some elements to ensure duplicate resources are not loaded.
450
517
451
-
To maintain compatibility with HTML and optimize performance, React will dedupe and hoist some but not all elements for all props. For the specific constraints, read the docs for [Resource and Metadata Components](/reference/react-dom/components#resource-and-metadata-components).
518
+
To optimize performance, React will dedupe elements if they refer to equivalent resources. For more details, read the docs for [Resource and Metadata Components](/reference/react-dom/components#resource-and-metadata-components).
452
519
453
520
### Compatability with third-party scripts and extensions {/*compatability-with-third-party-scripts-and-extensions*/}
454
521
@@ -526,76 +593,6 @@ Additionally, we've added two new root options to complement `onRecoverableError
526
593
527
594
For more info and examples, see the docs for [`createRoot`](/reference/react-dom/client/createRoot) and [`hydrateRoot`](/reference/react-dom/client/createRoot).
528
595
529
-
### Diffs for Hydration Errors {/*diffs-for-hydration-errors*/}
530
-
531
-
We also improved error reporting for hydration errors. For example, instead of logging multiple errors in DEV without any information about the mismatch:
532
-
533
-
<ConsoleBlockMulti>
534
-
535
-
<ConsoleLogLine level="error">
536
-
537
-
Warning: Text content did not match. Server: "Server" Client: "Client"
538
-
{''}at span
539
-
{''}at App
540
-
541
-
</ConsoleLogLine>
542
-
543
-
<ConsoleLogLine level="error">
544
-
545
-
Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div\>.
546
-
547
-
</ConsoleLogLine>
548
-
549
-
<ConsoleLogLine level="error">
550
-
551
-
Warning: Text content did not match. Server: "Server" Client: "Client"
552
-
{''}at span
553
-
{''}at App
554
-
555
-
</ConsoleLogLine>
556
-
557
-
<ConsoleLogLine level="error">
558
-
559
-
Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div\>.
560
-
561
-
</ConsoleLogLine>
562
-
563
-
<ConsoleLogLine level="error">
564
-
565
-
Uncaught Error: Text content does not match server-rendered HTML.
566
-
{''}at checkForUnmatchedText
567
-
{''}...
568
-
569
-
</ConsoleLogLine>
570
-
571
-
</ConsoleBlockMulti>
572
-
573
-
We now log a single message with a diff of the mismatch:
574
-
575
-
576
-
<ConsoleBlockMulti>
577
-
578
-
<ConsoleLogLine level="error">
579
-
580
-
Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if an SSR-ed Client Component used:{'\n'}
0 commit comments