Bump ViewTransition and Fragment ref docs to canary (#8048)

This commit is contained in:
Sebastian "Sebbie" Silbermann
2025-10-07 08:08:39 -07:00
committed by GitHub
parent 28e9bd9fa2
commit 249535378a
5 changed files with 126 additions and 143 deletions

View File

@@ -1245,8 +1245,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -1299,7 +1299,8 @@ By default, View Transitions include the browser default cross-fade animation. A
<Sandpack>
```js src/App.js active
import {unstable_ViewTransition as ViewTransition} from 'react'; import Details from './Details'; import Home from './Home'; import {useRouter} from './router';
import {ViewTransition} from 'react'; import Details from './Details';
import Home from './Home'; import {useRouter} from './router';
export default function App() {
const {url} = useRouter();
@@ -1562,7 +1563,7 @@ export function IconSearch(props) {
```
```js src/Layout.js
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -2441,8 +2442,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -2510,7 +2511,7 @@ Now, the cross fade is slower:
<Sandpack>
```js src/App.js active
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -2776,7 +2777,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -3669,8 +3670,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -3703,7 +3704,7 @@ Now the video thumbnail animates between the two pages:
<Sandpack>
```js src/App.js
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -3970,7 +3971,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -4027,7 +4028,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js active
import { useState, unstable_ViewTransition as ViewTransition } from "react"; import LikeButton from "./LikeButton"; import { useRouter } from "./router"; import { PauseIcon, PlayIcon } from "./Icons"; import { startTransition } from "react";
import { useState, ViewTransition } from "react"; import LikeButton from "./LikeButton"; import { useRouter } from "./router"; import { PauseIcon, PlayIcon } from "./Icons"; import { startTransition } from "react";
export function Thumbnail({ video, children }) {
// Add a name to animate with a shared element transition.
@@ -4878,8 +4879,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -4960,7 +4961,7 @@ Now we can animate the header along with thumbnail based on navigation type:
<Sandpack>
```js src/App.js hidden
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -5225,7 +5226,7 @@ export function IconSearch(props) {
```
```js src/Layout.js active
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -5289,7 +5290,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -5440,7 +5441,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -6194,8 +6195,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -6228,7 +6229,7 @@ By adding this, the fallback will cross-fade into the content. Click a video and
<Sandpack>
```js src/App.js hidden
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -6246,7 +6247,7 @@ export default function App() {
```
```js src/Details.js active
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
function VideoDetails({ id }) {
// Cross-fade the fallback to content.
@@ -6496,7 +6497,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react';
import {ViewTransition} from 'react';
import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
@@ -6561,7 +6562,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -6712,7 +6713,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js hidden
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -7492,8 +7493,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -7542,7 +7543,7 @@ Now, the Suspense content replaces the fallback with a sliding animation:
<Sandpack>
```js src/App.js hidden
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -7560,7 +7561,7 @@ export default function App() {
```
```js src/Details.js active
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
function VideoDetails({ id }) {
return (
@@ -7817,7 +7818,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react';
import {ViewTransition} from 'react';
import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
@@ -7882,7 +7883,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -8033,7 +8034,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js hidden
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -8813,8 +8814,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -8856,7 +8857,7 @@ Now the items animate as you type in the search bar:
<Sandpack>
```js src/App.js hidden
import { unstable_ViewTransition as ViewTransition } from "react";
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";
@@ -8874,7 +8875,7 @@ export default function App() {
```
```js src/Details.js hidden
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react";
import { use, Suspense, ViewTransition } from "react";
import { fetchVideo, fetchVideoDetails } from "./data";
import { Thumbnail, VideoControls } from "./Videos";
import { useRouter } from "./router";
@@ -8949,7 +8950,7 @@ function VideoInfo({ id }) {
```
```js src/Home.js
import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
import { useId, useState, use, useDeferredValue, ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
function SearchList({searchText, videos}) {
// Activate with useDeferredValue ("when")
@@ -9144,7 +9145,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react';
import {ViewTransition} from 'react';
import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
@@ -9209,7 +9210,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -9360,7 +9361,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js hidden
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -10154,8 +10155,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -10180,7 +10181,7 @@ Let's remove the slow fade, and take a look at the final result:
<Sandpack>
```js src/App.js
import {unstable_ViewTransition as ViewTransition} from 'react'; import Details from './Details'; import Home from './Home'; import {useRouter} from './router';
import {ViewTransition} from 'react'; import Details from './Details'; import Home from './Home'; import {useRouter} from './router';
export default function App() {
const {url} = useRouter();
@@ -10195,7 +10196,7 @@ export default function App() {
```
```js src/Details.js
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
function VideoDetails({id}) {
// Animate from Suspense fallback to content
@@ -10265,7 +10266,7 @@ function VideoInfo({ id }) {
```
```js src/Home.js
import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
import { useId, useState, use, useDeferredValue, ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
function SearchList({searchText, videos}) {
// Activate with useDeferredValue ("when")
@@ -10460,7 +10461,7 @@ export function IconSearch(props) {
```
```js src/Layout.js
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -10524,7 +10525,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js
import { useState, unstable_ViewTransition as ViewTransition } from "react"; import LikeButton from "./LikeButton"; import { useRouter } from "./router"; import { PauseIcon, PlayIcon } from "./Icons"; import { startTransition } from "react";
import { useState, ViewTransition } from "react"; import LikeButton from "./LikeButton"; import { useRouter } from "./router"; import { PauseIcon, PlayIcon } from "./Icons"; import { startTransition } from "react";
export function Thumbnail({ video, children }) {
// Add a name to animate with a shared element transition.
@@ -10672,7 +10673,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -11440,8 +11441,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -11542,7 +11543,7 @@ Try searching for a video, selecting it, and clicking "back":
<Sandpack>
```js src/App.js
import { unstable_ViewTransition as ViewTransition } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;
import { ViewTransition } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;
export default function App() {
const { url } = useRouter();
@@ -11561,7 +11562,7 @@ export default function App() {
```
```js src/Details.js hidden
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react";
import { use, Suspense, ViewTransition } from "react";
import { fetchVideo, fetchVideoDetails } from "./data";
import { Thumbnail, VideoControls } from "./Videos";
import { useRouter } from "./router";
@@ -11636,7 +11637,7 @@ function VideoInfo({ id }) {
```
```js src/Home.js hidden
import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
import { useId, useState, use, useDeferredValue, ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
function SearchList({searchText, videos}) {
// Activate with useDeferredValue ("when")
@@ -11831,7 +11832,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -11895,7 +11896,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -12046,7 +12047,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js hidden
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -12839,8 +12840,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
@@ -12879,7 +12880,7 @@ With this update, if the content on the next page has time to pre-render, it wil
<Sandpack>
```js src/App.js
import { unstable_ViewTransition as ViewTransition, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data'; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;
import { ViewTransition, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data'; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;
export default function App() {
const { url } = useRouter();
@@ -12903,7 +12904,7 @@ export default function App() {
```
```js src/Details.js
import { use, Suspense, unstable_ViewTransition as ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";
function VideoDetails({id}) {
// Animate from Suspense fallback to content.
@@ -12974,7 +12975,7 @@ function VideoInfo({ id }) {
```
```js src/Home.js hidden
import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
import { useId, useState, use, useDeferredValue, ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";
function SearchList({searchText, videos}) {
// Activate with useDeferredValue ("when")
@@ -13169,7 +13170,7 @@ export function IconSearch(props) {
```
```js src/Layout.js hidden
import {unstable_ViewTransition as ViewTransition} from 'react'; import { useIsNavPending } from "./router";
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";
export default function Page({ heading, children }) {
const isPending = useIsNavPending();
@@ -13233,7 +13234,7 @@ export default function LikeButton({video}) {
```
```js src/Videos.js hidden
import { useState, unstable_ViewTransition as ViewTransition } from "react";
import { useState, ViewTransition } from "react";
import LikeButton from "./LikeButton";
import { useRouter } from "./router";
import { PauseIcon, PlayIcon } from "./Icons";
@@ -13384,7 +13385,7 @@ export function fetchVideoDetails(id) {
```
```js src/router.js hidden
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, unstable_addTransitionType as addTransitionType} from "react";
import {useState, createContext, use, useTransition, useLayoutEffect, useEffect, addTransitionType} from "react";
export function Router({ children }) {
const [isPending, startTransition] = useTransition();
@@ -14177,8 +14178,8 @@ root.render(
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {

View File

@@ -6,7 +6,7 @@ title: <Fragment> (<>...</>)
`<Fragment>`, often used via `<>...</>` syntax, lets you group elements without a wrapper node.
<Experimental> Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements. See reference and usage below.</Experimental>
<Canary> Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements. See reference and usage below.</Canary>
```js
<>
@@ -30,9 +30,9 @@ Wrap elements in `<Fragment>` to group them together in situations where you nee
#### Props {/*props*/}
- **optional** `key`: Fragments declared with the explicit `<Fragment>` syntax may have [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key)
- <ExperimentalBadge /> **optional** `ref`: A ref object (e.g. from [`useRef`](/reference/react/useRef)) or [callback function](/reference/react-dom/components/common#ref-callback). React provides a `FragmentInstance` as the ref value that implements methods for interacting with the DOM nodes wrapped by the Fragment.
- <CanaryBadge /> **optional** `ref`: A ref object (e.g. from [`useRef`](/reference/react/useRef)) or [callback function](/reference/react-dom/components/common#ref-callback). React provides a `FragmentInstance` as the ref value that implements methods for interacting with the DOM nodes wrapped by the Fragment.
### <ExperimentalBadge /> FragmentInstance {/*fragmentinstance*/}
### <CanaryBadge /> FragmentInstance {/*fragmentinstance*/}
When you pass a ref to a fragment, React provides a `FragmentInstance` object with methods for interacting with the DOM nodes wrapped by the fragment:
@@ -64,7 +64,7 @@ When you pass a ref to a fragment, React provides a `FragmentInstance` object wi
- React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<><Child /></>` to `[<Child />]` or back, or when you go from rendering `<><Child /></>` to `<Child />` and back. This only works a single level deep: for example, going from `<><><Child /></></>` to `<Child />` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b)
- <ExperimentalBadge /> If you want to pass `ref` to a Fragment, you can't use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment ref={yourRef}>...</Fragment>`.
- <CanaryBadge /> If you want to pass `ref` to a Fragment, you can't use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment ref={yourRef}>...</Fragment>`.
---
@@ -242,7 +242,7 @@ function PostBody({ body }) {
---
### <ExperimentalBadge /> Using Fragment refs for DOM interaction {/*using-fragment-refs-for-dom-interaction*/}
### <CanaryBadge /> Using Fragment refs for DOM interaction {/*using-fragment-refs-for-dom-interaction*/}
Fragment refs allow you to interact with the DOM nodes wrapped by a Fragment without adding extra wrapper elements. This is useful for event handling, visibility tracking, focus management, and replacing deprecated patterns like `ReactDOM.findDOMNode()`.
@@ -262,7 +262,7 @@ function ClickableFragment({ children, onClick }) {
```
---
### <ExperimentalBadge /> Tracking visibility with Fragment refs {/*tracking-visibility-with-fragment-refs*/}
### <CanaryBadge /> Tracking visibility with Fragment refs {/*tracking-visibility-with-fragment-refs*/}
Fragment refs are useful for visibility tracking and intersection observation. This enables you to monitor when content becomes visible without requiring the child Components to expose refs:
@@ -309,7 +309,7 @@ This pattern is an alternative to Effect-based visibility logging, which is an a
---
### <ExperimentalBadge /> Focus management with Fragment refs {/*focus-management-with-fragment-refs*/}
### <CanaryBadge /> Focus management with Fragment refs {/*focus-management-with-fragment-refs*/}
Fragment refs provide focus management methods that work across all DOM nodes within the Fragment:

View File

@@ -1,21 +1,15 @@
---
title: <ViewTransition>
version: experimental
version: canary
---
<Experimental>
<Canary>
**This API is experimental and is not available in a stable version of React yet.**
**The `<ViewTransition />` API is currently only available in Reacts Canary and Experimental channels.**
You can try it by upgrading React packages to the most recent experimental version:
[Learn more about Reacts release channels here.](/community/versioning-policy#all-release-channels)
- `react@experimental`
- `react-dom@experimental`
- `eslint-plugin-react-hooks@experimental`
Experimental versions of React may contain bugs. Don't use them in production.
</Experimental>
</Canary>
<Intro>
@@ -23,7 +17,7 @@ Experimental versions of React may contain bugs. Don't use them in production.
```js
import {unstable_ViewTransition as ViewTransition} from 'react';
import {ViewTransition} from 'react';
<ViewTransition>
<div>...</div>
@@ -212,7 +206,7 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from 'react';
@@ -341,8 +335,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -383,7 +377,7 @@ If Transition first unmounts one side and then leads to a `<Suspense>` fallback
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from "react";
@@ -407,7 +401,7 @@ export default function Component() {
```
```js src/Video.js
import {unstable_ViewTransition as ViewTransition} from "react";
import {ViewTransition} from "react";
const THUMBNAIL_NAME = "video-thumbnail"
@@ -581,8 +575,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -663,7 +657,7 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from "react";
@@ -821,8 +815,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -869,7 +863,7 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from "react";
@@ -1025,8 +1019,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -1118,7 +1112,7 @@ export function VideoPlaceholder() {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition,
Suspense
@@ -1290,8 +1284,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -1391,7 +1385,7 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from 'react';
@@ -1528,8 +1522,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -1572,7 +1566,7 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
ViewTransition,
useState,
startTransition
} from 'react';
@@ -1780,8 +1774,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}
@@ -1844,8 +1838,8 @@ export function Video({ video }) {
```js
import {
unstable_ViewTransition as ViewTransition,
unstable_addTransitionType as addTransitionType,
ViewTransition,
addTransitionType,
useState,
startTransition,
} from "react";
@@ -2109,8 +2103,8 @@ button:hover {
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
}
}

View File

@@ -1,30 +1,24 @@
---
title: unstable_addTransitionType
version: experimental
title: addTransitionType
version: canary
---
<Experimental>
<Canary>
**This API is experimental and is not available in a stable version of React yet.**
**The `addTransitionType` API is currently only available in Reacts Canary and Experimental channels.**
You can try it by upgrading React packages to the most recent experimental version:
[Learn more about Reacts release channels here.](/community/versioning-policy#all-release-channels)
- `react@experimental`
- `react-dom@experimental`
- `eslint-plugin-react-hooks@experimental`
Experimental versions of React may contain bugs. Don't use them in production.
</Experimental>
</Canary>
<Intro>
`unstable_addTransitionType` lets you specify the cause of a transition.
`addTransitionType` lets you specify the cause of a transition.
```js
startTransition(() => {
unstable_addTransitionType('my-transition-type');
addTransitionType('my-transition-type');
setState(newState);
});
```
@@ -60,13 +54,13 @@ startTransition(() => {
Call `addTransitionType` inside of `startTransition` to indicate the cause of a transition:
``` [[1, 6, "unstable_addTransitionType"], [2, 5, "startTransition", [3, 6, "'submit-click'"]]
import { startTransition, unstable_addTransitionType } from 'react';
``` [[1, 6, "addTransitionType"], [2, 5, "startTransition", [3, 6, "'submit-click'"]]
import { startTransition, addTransitionType } from 'react';
function Submit({action) {
function handleClick() {
startTransition(() => {
unstable_addTransitionType('submit-click');
addTransitionType('submit-click');
action();
});
}
@@ -103,7 +97,7 @@ function Component() {
}
startTransition(() => {
unstable_addTransitionType('my-transition-type');
addTransitionType('my-transition-type');
setShow(true);
});
```
@@ -135,7 +129,7 @@ function Component() {
// ...
startTransition(() => {
unstable_addTransitionType('my-transition-type');
addTransitionType('my-transition-type');
setState(newState);
});
```
@@ -174,9 +168,3 @@ You can imperatively customize animations for an activated `ViewTransition` base
```
This allows you to pick different imperative Animations based on the cause.
---
## Troubleshooting {/*troubleshooting*/}
### TODO {/*todo2*/}

View File

@@ -115,7 +115,7 @@
{
"title": "<ViewTransition>",
"path": "/reference/react/ViewTransition",
"version": "experimental"
"version": "canary"
}
]
},
@@ -127,6 +127,11 @@
"title": "act",
"path": "/reference/react/act"
},
{
"title": "addTransitionType",
"path": "/reference/react/addTransitionType",
"version": "canary"
},
{
"title": "cache",
"path": "/reference/react/cache"
@@ -168,11 +173,6 @@
"title": "experimental_taintUniqueValue",
"path": "/reference/react/experimental_taintUniqueValue",
"version": "experimental"
},
{
"title": "unstable_addTransitionType",
"path": "/reference/react/addTransitionType",
"version": "experimental"
}
]
},