Skip to content

Commit 4f76cdc

Browse files
committed
wip
1 parent 63e6479 commit 4f76cdc

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ We're also sharing updates on new features currently in development:
3636
- [Compiler IDE Extension](#compiler-ide-extension)
3737
- [Automatic Effect Dependencies](#automatic-effect-dependencies)
3838
- [Fragment Refs](#fragment-refs)
39-
- [Concurrent stores](#concurrent-stores)
39+
- [Concurrent Stores](#concurrent-stores)
4040

4141
---
4242

4343
# New Experimental Features {/*new-experimental-features*/}
4444

45-
View Transitions and Activity are now ready for testing in `react@experimental`.These features have been tested in production and are stable, but the final API may still change as we incorporate feedback.
46-
47-
45+
View Transitions and Activity are now ready for testing in `react@experimental`. These features have been tested in production and are stable, but the final API may still change as we incorporate feedback.
4846

4947
You can try them by upgrading React packages to the most recent experimental version:
5048

@@ -63,7 +61,6 @@ React View Transitions are a new experimental feature that makes it easier to ad
6361

6462
To opt-in to animating an element, wrap it in the new `<ViewTransition>` component:
6563

66-
6764
```js
6865
// "what" to animate.
6966
<ViewTransition>
@@ -11532,7 +11529,7 @@ For example, our app currently needs to suspend to load the data for each video
1153211529
<ViewTransition>
1153311530
```
1153411531

11535-
With this update, if you select a video after 1 second, the content has time to pre-render and animates without the Suspense fallback:
11532+
With this update, if the content on the next page has time to pre-render, it will animate in without the Suspense fallback. Click a video, and notice that the video title and description on the Details page render immediately, without a fallback:
1153611533

1153711534
<Sandpack>
1153811535

@@ -12848,10 +12845,40 @@ root.render(
1284812845

1284912846
</Sandpack>
1285012847

12848+
### Server-Side Rendering with Activity {/*server-side-rendering-with-activity*/}
12849+
12850+
When using Activity on a page that uses server-side rendering (SSR), there are additional optimizations.
12851+
12852+
If part of the page is rendered with `mode="hidden"`, then it will not be included in the SSR response. Instead, React will schedule a client render for the content inside Activity while the rest of the page hydrates, prioritizing the visible content on screen.
12853+
12854+
For parts of the UI rendered with `mode="visible"`, React will de-prioirtize hydration of content within Activity, similar to how Suspense content is hydrated at a lower priority. If the user interacts with the page, we'll priorize hydration within the boundary if needed.
12855+
12856+
These are advanced use cases, but they show the additional benefits considered with Activity.
12857+
12858+
### Future modes for Activity {/*future-modes-for-activity*/}
12859+
12860+
In the future, we may add more modes to Activity.
12861+
12862+
For example, a common use case is rendering a modal, where the previous "inactive" page is visible behind the "active" modal view. The "hidden" mode does not work for this use case, because it's not visible, and not included in SSR.
12863+
12864+
Instead, we're considering a new mode which would keep the content visible, including rendering it during SSR, but keep it unmounted and de-prioritize updates. This mode may also need to "pause" DOM updates, since it can be distracting to see backgrounded content updating while a modal is open.
12865+
12866+
Another mode we're considering for Activity is the ability to automatically destroy state for hidden Activities if there is too much memory being used. Since the component is already unmounted, it may be preferable to destroy state for the least recently used hidden parts of the app, rather than consume too many resources.
12867+
12868+
These are areas we're still exporing, and we'll share more as we make progress. For more information on what Activity includes today, [check out the docs](/reference/react/Activity).
12869+
1285112870
---
1285212871

1285312872
# Features in development {/*features-in-development*/}
1285412873

12874+
We're also developing features to help solve the common problems below.
12875+
12876+
As we iterate on possible solutions, you may see some potenial APIs we're testing being shared based on the PRs we are landing. Please keep in mind, that as we try different ideas, we often change or remove different solutions after trying them out.
12877+
12878+
When the solutions we're working on are shared too early, it can create churn and confusion in the community. To balance being transparent and limiting confusion, we're sharing the problems we're currently developing solutions for, without sharing a particular solution we have in mind.
12879+
12880+
As these features progress, we'll announce them on the blog with docs included so you can try them out.
12881+
1285512882
## React Performance Tracks {/*react-performance-tracks*/}
1285612883

1285712884
We're working on a new set of custom tracks to performance profilers using browser APIs that [allow adding custom tracks](https://developer.chrome.com/docs/devtools/performance/extension) to provide more information about the performance of your React app.
@@ -12875,18 +12902,6 @@ Once we solve those issues, we'll publish experimental docs and share that it's
1287512902

1287612903
---
1287712904

12878-
## Compiler IDE Extension {/*compiler-ide-extension*/}
12879-
12880-
Earlier this week [we shared](/blog/2025/04/21/react-compiler-rc) the React Compiler release candidate, and we're working towards shipping the first SemVer stable version of the compiler in the coming months.
12881-
12882-
We've also begun exploring ways to use the React Compiler to provide information that can improve understanding and debugging your code. One idea we've started exploring is a new experimental LSP-based React IDE extension powered by React Compiler, similar to the extension used in [Lauren Tan's React Conf talk](https://conf2024.react.dev/talks/5).
12883-
12884-
Our idea is that we can use the compiler's static analysis to provide more information, suggestions, and optimization opportunities directly in your IDE. For example, we can provide diagnostics for code breaking the Rules of React, hovers to show if components and hooks were optimized by the compiler, or a CodeLens to see [automatically inserted Effect dependencies](#automatic-effect-dependencies).
12885-
12886-
The IDE extension is still an early exploration, but we'll share our progress in future updates.
12887-
12888-
---
12889-
1289012905
## Automatic Effect Dependencies {/*automatic-effect-dependencies*/}
1289112906

1289212907
When we released hooks, we had three motivations:
@@ -12919,11 +12934,11 @@ useEffect(() => {
1291912934
}, [roomId]);
1292012935
```
1292112936

12922-
Many users would read this code as "on mount, connect to the roomId. whenever `roomId` changes, disconnect to the old room and re-create the connection". However, this is thinking from the component's lifecycle perspective, which means you will need to think of every component lifecycle state to write the effect correctly. This can be difficult, so it's understandble that Effects seem harder than class lifecycles when using component perspective.
12937+
Many users would read this code as "on mount, connect to the roomId. whenever `roomId` changes, disconnect to the old room and re-create the connection". However, this is thinking from the component's lifecycle perspective, which means you will need to think of every component lifecycle state to write the Effect correctly. This can be difficult, so it's understandble that Effects seem harder than class lifecycles when using component perspective.
1292312938

1292412939
### Effects without dependencies {/*effects-without-dependencies*/}
1292512940

12926-
Instead, it's better to think from the Effect's perspective. The effect doesn't know about the component lifecycles. It only describes how to start synchronization and how to stop it. When users think of Effects in this way, their Effects tend to be easier to write, and more resilient to being started and stopped as many times as it’s needed.
12941+
Instead, it's better to think from the Effect's perspective. The Effect doesn't know about the component lifecycles. It only describes how to start synchronization and how to stop it. When users think of Effects in this way, their Effects tend to be easier to write, and more resilient to being started and stopped as many times as it’s needed.
1292712942

1292812943
We spent some time researching why Effects are thought of from the component perspective, and we think one of the resons is the dependency array. Since you have to write it, it's right there and in your face reminding you of what you're "reacting" to and baiting you into the mental model of 'do this when these values change'.
1292912944

@@ -12939,15 +12954,27 @@ useEffect(() => {
1293912954
}); // compiler inserted dependencies.
1294012955
```
1294112956

12942-
With this code, the React Compiler can infer the dependencies for you and insert them automatically so you don't need to see or write them. With features like the IDE exension and `useEffectEvent`, we can provide a CodeLens to show you what the Compiler inserted for times you need to debug, or to optimize by removing a dependency. This helps reinforce the correct mental model for writing Effects, which can run at any time to synchronize your component or hook's state with something else.
12957+
With this code, the React Compiler can infer the dependencies for you and insert them automatically so you don't need to see or write them. With features like [the IDE exension](#compiler-ide-extension) and [`useEffectEvent`](/reference/react/experimental_useEffectEvent), we can provide a CodeLens to show you what the Compiler inserted for times you need to debug, or to optimize by removing a dependency. This helps reinforce the correct mental model for writing Effects, which can run at any time to synchronize your component or hook's state with something else.
1294312958

12944-
Our hope is that automatically inserting dependencies is not only easier to write, but that it also makes them easier to understand by forcing you to think in terms of what the effect does, and not in component lifecycles.
12959+
Our hope is that automatically inserting dependencies is not only easier to write, but that it also makes them easier to understand by forcing you to think in terms of what the Effect does, and not in component lifecycles.
12960+
12961+
---
12962+
12963+
## Compiler IDE Extension {/*compiler-ide-extension*/}
12964+
12965+
Earlier this week [we shared](/blog/2025/04/21/react-compiler-rc) the React Compiler release candidate, and we're working towards shipping the first SemVer stable version of the compiler in the coming months.
12966+
12967+
We've also begun exploring ways to use the React Compiler to provide information that can improve understanding and debugging your code. One idea we've started exploring is a new experimental LSP-based React IDE extension powered by React Compiler, similar to the extension used in [Lauren Tan's React Conf talk](https://conf2024.react.dev/talks/5).
12968+
12969+
Our idea is that we can use the compiler's static analysis to provide more information, suggestions, and optimization opportunities directly in your IDE. For example, we can provide diagnostics for code breaking the Rules of React, hovers to show if components and hooks were optimized by the compiler, or a CodeLens to see [automatically inserted Effect dependencies](#automatic-effect-dependencies).
12970+
12971+
The IDE extension is still an early exploration, but we'll share our progress in future updates.
1294512972

1294612973
---
1294712974

1294812975
## Fragment Refs {/*fragment-refs*/}
1294912976

12950-
Many DOM APIs like those for event management, positioning, and focus are difficult to compose when writing with React. This often leads developers to reach for Effects, managing multiple Refs, or APIs like `findDOMNode` (removed in React 19).
12977+
Many DOM APIs like those for event management, positioning, and focus are difficult to compose when writing with React. This often leads developers to reach for Effects, managing multiple Refs, by using APIs like `findDOMNode` (removed in React 19).
1295112978

1295212979
We are exploring adding refs to Fragments that would point to a group of DOM elements, rather than just a single element. Our hope is that this will simplify managing multiple children and make it easier to write composable React code when calling DOM APIs.
1295312980

@@ -12969,7 +12996,7 @@ We believe we’ve found an approach that works well and may introduce a new API
1296912996

1297012997
---
1297112998

12972-
## Concurrent stores {/*concurrent-stores*/}
12999+
## Concurrent Stores {/*concurrent-stores*/}
1297313000

1297413001
When we released React 18 with concurrent rendering, we also released `useSyncExternalStore` so external store libraries that did not use React state or context could [support concurrent rendering](https://github.com/reactwg/react-18/discussions/70) by forcing a sync render when the store is updated.
1297513002

@@ -12987,4 +13014,4 @@ This research is still early. We'll share more, and what the new APIs will look
1298713014

1298813015
---
1298913016

12990-
_TODO: Thanks to [Aurora Scharff](https://bsky.app/profile/aurorascharff.no), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Lauren Tan](https://bsky.app/profile/no.lol), [Luna Wei](https://github.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Jack Pope](https://jackpope.me), [Jason Bonta](https://threads.net/someextent), [Jordan Brown](https://github.com/jbrown215), [Jordan Eldredge](https://bsky.app/profile/capt.dev), [Mofei Zhang](https://threads.net/z_mofei), [Sebastien Lorber](https://bsky.app/profile/sebastienlorber.com), and [Sebastian Markbåge](https://bsky.app/profile/sebmarkbage.calyptus.eu) for reviewing this post.
13017+
_Thanks to [Aurora Scharff](https://bsky.app/profile/aurorascharff.no), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Eli White](https://twitter.com/Eli_White), [Lauren Tan](https://bsky.app/profile/no.lol), [Luna Wei](https://github.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Jack Pope](https://jackpope.me), [Jason Bonta](https://threads.net/someextent), [Jordan Brown](https://github.com/jbrown215), [Jordan Eldredge](https://bsky.app/profile/capt.dev), [Mofei Zhang](https://threads.net/z_mofei), [Sebastien Lorber](https://bsky.app/profile/sebastienlorber.com), [Sebastian Markbåge](https://bsky.app/profile/sebmarkbage.calyptus.eu), and [Tim Yung](https://github.com/yungsters) for reviewing this post._

src/content/reference/react/Activity.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ Under the hood...
7070

7171
- While hidden, the `children` of `<Activity>` are hidden on the page.
7272
- `<Activity>` will unmount all Effects when switching from "visible" to "hidden" without destroying React or DOM state. This means Effects that expect to only run "once" on "mount" will run again when switching from "hidden" to "visible". Conceptually, "hidden" Activities are unmounted, but they are not destroyed either. We recommend using [`<StrictMode>`](/reference/react/StrictMode) to catch any unexpected side-effects from this behavior.
73-
- Parts of the UI wrapped in `<Activity mode="hidden">` are not included in the SSR response.
7473
- When used with `<ViewTransition>`, hidden activities that reveal in a transition will activate an "enter" animation. Visible Activities hidden in a transition will activate an "exit" animation.
74+
- Parts of the UI wrapped in `<Activity mode="hidden">` are not included in the SSR response.
75+
- Parts of the UI wrapped in `<Activity mode="visible">` will hydrate at a lower priority than other content.
7576

7677
---
7778

0 commit comments

Comments
 (0)