Skip to content

Commit c33b34e

Browse files
committed
Feedback
1 parent b441686 commit c33b34e

File tree

2 files changed

+60
-31
lines changed

2 files changed

+60
-31
lines changed

src/content/blog/2024/04/25/react-19-upgrade-guide.md

+12-9
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ To help make the upgrade easier, today we are also publishing React 18.3.
2525

2626
#### React 18.3 has also been published {/*react-18-3*/}
2727

28-
To help make the upgrade to React 19 easier, we've published a `[email protected]` release that only includes warnings for deprecated APIs and other changes that are needed for React 19.
28+
To help make the upgrade to React 19 easier, we've published a `[email protected]` release that is identical to 18.2 but adds warnings for deprecated APIs and other changes that are needed for React 19.
2929

3030
We recommend upgrading to React 18.3 first to help identify any issues before upgrading to React 19.
3131

@@ -440,20 +440,23 @@ We are deprecating `react-test-renderer` because it implements its own renderer
440440

441441
The test renderer was created before there were more viable testing strategies available like [React Testing Library](https://testing-library.com), and we now recommend using a modern testing library instead.
442442

443-
In React 19, `react-test-renderer` log a deprecation warning, and has switched to concurrent rendering. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/docs/getting-started) for a modern and well supported testing experience.
443+
In React 19, `react-test-renderer` logs a deprecation warning, and has switched to concurrent rendering. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/docs/getting-started) for a modern and well supported testing experience.
444444

445445
## Notable Changes {/*notable-changes*/}
446446

447447
### StrictMode changes {/*strict-mode-improvements*/}
448448

449-
TODO
449+
React 19 includes several fixes and improvements to Strict Mode.
450450

451-
- https://github.com/facebook/react/pull/25583
452-
- https://github.com/facebook/react/pull/25049
451+
When double rendering in Strict Mode in development, `useMemo` and `useCallback` will reuse the memoized results from the first render during the second render. Components that are already Strict Mode compatible should not notice a difference in behavior.
452+
453+
As with all Strict Mode behaviors, these features are designed to proactively surface bugs in your components during development so you can fix them before they are shipped to production. For example, during development, Strict Mode will double-invoke ref callback functions on initial mount, to simulate what happens when a mounted component is replaced by a Suspense fallback.
453454

454455
### UMD builds removed {/*umd-builds-removed*/}
455456

456-
UMD was widely used in the past as a convenient way to load React without a build step. Now, there are modern alternatives for loading modules as scripts in HTML documents. Starting with React 19, React will no longer produce UMD builds to reduce the complexity of its testing and release process. If you want to load React 19 using a script tag, we recommend using an ESM-based CDN such as [esm.sh](https://esm.sh/).
457+
UMD was widely used in the past as a convenient way to load React without a build step. Now, there are modern alternatives for loading modules as scripts in HTML documents. Starting with React 19, React will no longer produce UMD builds to reduce the complexity of its testing and release process.
458+
459+
To load React 19 with a script tag, we recommend using an ESM-based CDN such as [esm.sh](https://esm.sh/).
457460

458461
```html
459462
<script type="module">
@@ -506,9 +509,9 @@ _This change is included in the `react-19` codemod preset as [`no-implicit-ref-c
506509

507510
Due to the introduction of ref cleanup functions, returning anything else from a ref callback will now be rejected by TypeScript. The fix is usually to stop using implicit returns:
508511

509-
```diff
510-
-<div ref={current => (instance = current)} />
511-
+<div ref={current => {instance = current}} />
512+
```diff [[1, 1, "("], [1, 1, ")"], [2, 2, "{", 15], [2, 2, "}", 1]]
513+
- <div ref={current => (instance = current)} />
514+
+ <div ref={current => {instance = current}} />
512515
```
513516

514517
The original code returned the instance of the `HTMLDivElement` and TypeScript wouldn't know if this was supposed to be a cleanup function or not.

src/content/blog/2024/04/25/react-19.md

+48-22
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,44 @@ function Comments({commentsPromise}) {
252252
}
253253
```
254254

255-
Or you can read context with `use`:
255+
<Note>
256256

257-
```js {1,5}
258-
import {use} from 'react';
259-
import ThemeContext from './ThemeContext'
257+
#### `use` does not support promises created in render. {/*use-does-not-support-promises-created-in-render*/}
258+
259+
If you try to pass a promise created in render to `use`, React will warn:
260+
261+
<ConsoleBlockMulti>
262+
263+
<ConsoleLogLine level="error">
264+
265+
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
266+
267+
</ConsoleLogLine>
268+
269+
</ConsoleBlockMulti>
270+
271+
To fix, you need to pass a promise from a suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.
272+
273+
</Note>
274+
275+
You can also read context with `use`, allowing you to react Context conditionally:
260276

261-
function ThemedPage({children}) {
262-
const theme = use(ThemeContext);
277+
```js {1,8,10}
278+
import {use} from 'react';
279+
import LightThemeContext from './LightThemeContext'
280+
import DarkThemeContext from './ThemeContext'
281+
282+
function ThemedPage({theme, children}) {
283+
let theme;
284+
if (theme === 'dark') {
285+
theme = use(DarkThemeContext);
286+
} else {
287+
theme = use(LightThemeContext);
288+
}
263289
return (
264-
<div className={theme === 'dark' ? 'dark' : 'light'}>
290+
<Page theme={theme}>
265291
{children}
266-
</div>
292+
</Page>
267293
);
268294
}
269295
```
@@ -321,9 +347,9 @@ For more, see the docs for [React Server Actions](/reference/rsc/server-actions)
321347

322348
Starting in React 19, you can now access `ref` as a prop for function components:
323349

324-
```js [[1, 1, "ref"], [1, 2, "ref", 20]]
325-
function MyInput({ref}) {
326-
return <input ref={ref} />
350+
```js [[1, 1, "ref"], [1, 2, "ref", 45], [1, 6, "ref", 14]]
351+
function MyInput({placeholder, ref}) {
352+
return <input placeholder={placeholder} ref={ref} />
327353
}
328354

329355
//...
@@ -432,19 +458,17 @@ New Context providers can use `<Context>` and we will be publishing a codemod to
432458
We now support returning a cleanup function from `ref` callbacks:
433459

434460
```js {7-11}
435-
function Input() {
436-
const ref = useRef();
437-
438-
return <input ref={(ref) => {
439-
ref.current = ref;
461+
<input
462+
ref={(ref) => {
463+
// ref created
440464

441465
// NEW: return a cleanup funtion to reset
442-
// the ref when element is removed from DOM.
466+
// the ref when element is removed from DOM.
443467
return () => {
444-
ref.current = null;
445-
}
446-
}} />;
447-
}
468+
// ref cleanup
469+
};
470+
}}
471+
/>
448472
```
449473

450474
When the component unmounts, React will call the cleanup function returned from the ref callback. This works for DOM refs, refs to class components, and `useImperitiveHandle`.
@@ -570,7 +594,9 @@ For more details, read the docs for [`<link>`](/reference/react-dom/components/l
570594
571595
### Support for async scripts {/*support-for-async-scripts*/}
572596
573-
In HTML normal scripts (`<script src="...">`) and deferred scripts (`<script defer="" src="...">`) load in document order which makes rendering these kinds of scripts deep within your component tree challenging. Async scripts (`<script async="" src="...">`) however will load in arbitrary order and in React 19 we've included better support for async scripts by allowing you to render them anywhere in your component tree, inside the components that actually depend on the script, without having to manage relocating and deduplicating script instances.
597+
In HTML normal scripts (`<script src="...">`) and deferred scripts (`<script defer="" src="...">`) load in document order which makes rendering these kinds of scripts deep within your component tree challenging. Async scripts (`<script async="" src="...">`) however will load in arbitrary order.
598+
599+
In React 19 we've included better support for async scripts by allowing you to render them anywhere in your component tree, inside the components that actually depend on the script, without having to manage relocating and deduplicating script instances.
574600
575601
```js
576602
function MyComponent() {

0 commit comments

Comments
 (0)