Skip to content

Commit

Permalink
Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
rickhanlonii committed Apr 25, 2024
1 parent b441686 commit c33b34e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 31 deletions.
21 changes: 12 additions & 9 deletions src/content/blog/2024/04/25/react-19-upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ To help make the upgrade easier, today we are also publishing React 18.3.

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

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.
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.

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

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

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.

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.
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.

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

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

TODO
React 19 includes several fixes and improvements to Strict Mode.

- https://github.com/facebook/react/pull/25583
- https://github.com/facebook/react/pull/25049
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.

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.

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

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/).
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.

To load React 19 with a script tag, we recommend using an ESM-based CDN such as [esm.sh](https://esm.sh/).

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

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:

```diff
-<div ref={current => (instance = current)} />
+<div ref={current => {instance = current}} />
```diff [[1, 1, "("], [1, 1, ")"], [2, 2, "{", 15], [2, 2, "}", 1]]
- <div ref={current => (instance = current)} />
+ <div ref={current => {instance = current}} />
```

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.
Expand Down
70 changes: 48 additions & 22 deletions src/content/blog/2024/04/25/react-19.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,18 +252,44 @@ function Comments({commentsPromise}) {
}
```

Or you can read context with `use`:
<Note>

```js {1,5}
import {use} from 'react';
import ThemeContext from './ThemeContext'
#### `use` does not support promises created in render. {/*use-does-not-support-promises-created-in-render*/}

If you try to pass a promise created in render to `use`, React will warn:

<ConsoleBlockMulti>

<ConsoleLogLine level="error">

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.

</ConsoleLogLine>

</ConsoleBlockMulti>

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.

</Note>

You can also read context with `use`, allowing you to react Context conditionally:

function ThemedPage({children}) {
const theme = use(ThemeContext);
```js {1,8,10}
import {use} from 'react';
import LightThemeContext from './LightThemeContext'
import DarkThemeContext from './ThemeContext'

function ThemedPage({theme, children}) {
let theme;
if (theme === 'dark') {
theme = use(DarkThemeContext);
} else {
theme = use(LightThemeContext);
}
return (
<div className={theme === 'dark' ? 'dark' : 'light'}>
<Page theme={theme}>
{children}
</div>
</Page>
);
}
```
Expand Down Expand Up @@ -321,9 +347,9 @@ For more, see the docs for [React Server Actions](/reference/rsc/server-actions)

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

```js [[1, 1, "ref"], [1, 2, "ref", 20]]
function MyInput({ref}) {
return <input ref={ref} />
```js [[1, 1, "ref"], [1, 2, "ref", 45], [1, 6, "ref", 14]]
function MyInput({placeholder, ref}) {
return <input placeholder={placeholder} ref={ref} />
}

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

```js {7-11}
function Input() {
const ref = useRef();

return <input ref={(ref) => {
ref.current = ref;
<input
ref={(ref) => {
// ref created

// NEW: return a cleanup funtion to reset
// the ref when element is removed from DOM.
// the ref when element is removed from DOM.
return () => {
ref.current = null;
}
}} />;
}
// ref cleanup
};
}}
/>
```

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`.
Expand Down Expand Up @@ -570,7 +594,9 @@ For more details, read the docs for [`<link>`](/reference/react-dom/components/l
### Support for async scripts {/*support-for-async-scripts*/}
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.
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.
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.
```js
function MyComponent() {
Expand Down

0 comments on commit c33b34e

Please sign in to comment.