diff --git a/.claude/skills/docs-writer-blog/SKILL.md b/.claude/skills/docs-writer-blog/SKILL.md index ef28225f8..baa21c34d 100644 --- a/.claude/skills/docs-writer-blog/SKILL.md +++ b/.claude/skills/docs-writer-blog/SKILL.md @@ -159,7 +159,7 @@ See [How to Upgrade to React X.Y](/blog/YYYY/MM/DD/react-xy-upgrade-guide) for s ### React {/*react*/} -* Add `useNewHook` for [purpose]. ([#12345](https://github.com/facebook/react/pull/12345) by [@contributor](https://github.com/contributor)) +* Add `useNewHook` for [purpose]. ([#12345](https://github.com/react/react/pull/12345) by [@contributor](https://github.com/contributor)) --- @@ -603,7 +603,7 @@ npm install react@latest react-dom@latest | Type | Pattern | |------|---------| -| GitHub PR | `[#12345](https://github.com/facebook/react/pull/12345)` | +| GitHub PR | `[#12345](https://github.com/react/react/pull/12345)` | | GitHub user | `[@username](https://github.com/username)` | | Twitter/X | `[@username](https://x.com/username)` | | Bluesky | `[Name](https://bsky.app/profile/handle)` | @@ -623,8 +623,8 @@ For more information, see the docs for [`useActionState`](/reference/react/useAc ### Bullet Pattern ```markdown -* Add `useTransition` for concurrent rendering. ([#10426](https://github.com/facebook/react/pull/10426) by [@acdlite](https://github.com/acdlite)) -* Fix `useReducer` observing incorrect props. ([#22445](https://github.com/facebook/react/pull/22445) by [@josephsavona](https://github.com/josephsavona)) +* Add `useTransition` for concurrent rendering. ([#10426](https://github.com/react/react/pull/10426) by [@acdlite](https://github.com/acdlite)) +* Fix `useReducer` observing incorrect props. ([#22445](https://github.com/react/react/pull/22445) by [@josephsavona](https://github.com/josephsavona)) ``` **Structure:** `Verb` + backticked API + description + `([#PR](url) by [@user](url))` diff --git a/.claude/skills/react-expert/SKILL.md b/.claude/skills/react-expert/SKILL.md index 5ebcdee37..c252f6ce0 100644 --- a/.claude/skills/react-expert/SKILL.md +++ b/.claude/skills/react-expert/SKILL.md @@ -32,7 +32,7 @@ This skill produces exhaustive documentation research on any React API or concep 2. **React Source Code** - Warnings, errors, implementation details 3. **Git History** - Commit messages with context 4. **GitHub PRs & Comments** - Design rationale (via `gh` CLI) -5. **GitHub Issues** - Confusion/questions (facebook/react + reactjs/react.dev) +5. **GitHub Issues** - Confusion/questions (react/react + reactjs/react.dev) 6. **React Working Group** - Design discussions for newer APIs 7. **Flow Types** - Source of truth for type signatures 8. **TypeScript Types** - Note discrepancies with Flow @@ -51,7 +51,7 @@ First, ensure the React repo is available locally: if [ -d ".claude/react" ]; then cd .claude/react && git pull origin main else - git clone --depth=100 https://github.com/facebook/react.git .claude/react + git clone --depth=100 https://github.com/react/react.git .claude/react fi ``` @@ -71,8 +71,8 @@ Spawn these agents IN PARALLEL using the Task tool. Each agent receives the skep | test-explorer | Explore | Test files for usage patterns | Search `.claude/react/packages/*/src/__tests__/` for test files mentioning the topic. Extract actual usage examples WITH file paths and line numbers. | | source-explorer | Explore | Warnings/errors in source | Search `.claude/react/packages/*/src/` for console.error, console.warn, and error messages mentioning the topic. Document trigger conditions. | | git-historian | Explore | Commit messages | Run `git log --all --grep="" --oneline -50` in `.claude/react`. Read full commit messages for context. | -| pr-researcher | Explore | PRs introducing/modifying API | Run `gh pr list -R facebook/react --search "" --state all --limit 20`. Read key PR descriptions and comments. | -| issue-hunter | Explore | Issues showing confusion | Search issues in both `facebook/react` and `reactjs/react.dev` repos. Look for common questions and misunderstandings. | +| pr-researcher | Explore | PRs introducing/modifying API | Run `gh pr list -R react/react --search "" --state all --limit 20`. Read key PR descriptions and comments. | +| issue-hunter | Explore | Issues showing confusion | Search issues in both `react/react` and `reactjs/react.dev` repos. Look for common questions and misunderstandings. | | types-inspector | Explore | Flow + TypeScript signatures | Find Flow types in `.claude/react/packages/*/src/*.js` (look for `@flow` annotations). Find TS types in `.claude/react/packages/*/index.d.ts`. Note discrepancies. | ### Step 3: Agent Prompts @@ -164,8 +164,8 @@ CRITICAL: Do NOT rely on your prior knowledge. Only report what you find in PRs. Your task: Find PRs that introduced or modified . -1. Run: gh pr list -R facebook/react --search "" --state all --limit 20 --json number,title,url -2. For promising PRs, read details: gh pr view -R facebook/react +1. Run: gh pr list -R react/react --search "" --state all --limit 20 --json number,title,url +2. For promising PRs, read details: gh pr view -R react/react 3. Look for: - The original RFC/motivation - Design discussions in comments @@ -189,7 +189,7 @@ CRITICAL: Do NOT rely on your prior knowledge. Only report what you find in issu Your task: Find issues that reveal common confusion about . -1. Search facebook/react: gh issue list -R facebook/react --search "" --state all --limit 20 --json number,title,url +1. Search react/react: gh issue list -R react/react --search "" --state all --limit 20 --json number,title,url 2. Search reactjs/react.dev: gh issue list -R reactjs/react.dev --search "" --state all --limit 20 --json number,title,url 3. For each issue, identify: - What the user was confused about @@ -199,7 +199,7 @@ Your task: Find issues that reveal common confusion about . Format your output as: ## Common Confusion ### Issue #: -**Repo:** <facebook/react or reactjs/react.dev> +**Repo:** <react/react or reactjs/react.dev> **Confusion:** <what they misunderstood> **Resolution:** <correct understanding> **Gotcha:** <if applicable> diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 63e310e0b..de2bfc362 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,6 +1,6 @@ contact_links: - name: 📃 Bugs in React - url: https://github.com/facebook/react/issues/new/choose + url: https://github.com/react/react/issues/new/choose about: This issue tracker is not for bugs in React. Please file React issues here. - name: 🤔 Questions and Help url: https://reactjs.org/community/support.html diff --git a/.github/workflows/discord_notify.yml b/.github/workflows/discord_notify.yml index 2f5b2a497..97f8d183b 100644 --- a/.github/workflows/discord_notify.yml +++ b/.github/workflows/discord_notify.yml @@ -8,7 +8,7 @@ permissions: {} jobs: check_maintainer: - uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main + uses: react/react/.github/workflows/shared_check_maintainer.yml@main permissions: # Used by check_maintainer contents: read diff --git a/.github/workflows/label_core_team_prs.yml b/.github/workflows/label_core_team_prs.yml index f9b3328ee..4cb6fbc71 100644 --- a/.github/workflows/label_core_team_prs.yml +++ b/.github/workflows/label_core_team_prs.yml @@ -12,7 +12,7 @@ env: jobs: check_maintainer: - uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main + uses: react/react/.github/workflows/shared_check_maintainer.yml@main permissions: # Used by check_maintainer contents: read diff --git a/.gitignore b/.gitignore index 92626a1e6..ed9efe38d 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ public/rss.xml # worktrees .worktrees/ + +# Generated OG images (scripts/generateOgImages.mjs) +public/images/og/ diff --git a/package.json b/package.json index 3c1941531..d04a4a28d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "analyze": "ANALYZE=true next build", "dev": "next-remote-watch ./src/content", "prebuild:rsc": "node scripts/buildRscWorker.mjs", - "build": "node scripts/buildRscWorker.mjs && next build && node --experimental-modules ./scripts/downloadFonts.mjs", + "build": "node scripts/buildRscWorker.mjs && next build && node --experimental-modules ./scripts/downloadFonts.mjs && node ./scripts/generateOgImages.mjs", "lint": "next lint && eslint \"src/content/**/*.md\"", "lint:fix": "next lint --fix && eslint \"src/content/**/*.md\" --fix", "format:source": "prettier --config .prettierrc --write \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"", @@ -53,6 +53,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.18.6", "@babel/preset-react": "^7.18.6", "@mdx-js/mdx": "^2.1.3", + "@resvg/resvg-js": "^2.6.2", "@types/body-scroll-lock": "^2.6.1", "@types/classnames": "^2.2.10", "@types/debounce": "^1.2.1", @@ -104,6 +105,7 @@ "retext": "^7.0.1", "retext-smartypants": "^4.0.0", "rss": "^1.2.2", + "satori": "^0.26.0", "tailwindcss": "^3.4.1", "typescript": "^5.7.2", "unist-util-visit": "^2.0.3", diff --git a/public/fonts/Optimistic_Display_W_Bd.ttf b/public/fonts/Optimistic_Display_W_Bd.ttf new file mode 100644 index 000000000..9d0cff450 Binary files /dev/null and b/public/fonts/Optimistic_Display_W_Bd.ttf differ diff --git a/public/fonts/Optimistic_Display_W_Md.ttf b/public/fonts/Optimistic_Display_W_Md.ttf new file mode 100644 index 000000000..3fbdb483d Binary files /dev/null and b/public/fonts/Optimistic_Display_W_Md.ttf differ diff --git a/public/images/team/gh-aurorascharff.jpg b/public/images/team/gh-aurorascharff.jpg new file mode 100644 index 000000000..10476e5e8 Binary files /dev/null and b/public/images/team/gh-aurorascharff.jpg differ diff --git a/public/images/team/gh-brentvatne.jpg b/public/images/team/gh-brentvatne.jpg new file mode 100644 index 000000000..c66a5cd6d Binary files /dev/null and b/public/images/team/gh-brentvatne.jpg differ diff --git a/public/images/team/gh-captbaritone.jpg b/public/images/team/gh-captbaritone.jpg new file mode 100644 index 000000000..0100fa16b Binary files /dev/null and b/public/images/team/gh-captbaritone.jpg differ diff --git a/public/images/team/gh-cipolleschi.png b/public/images/team/gh-cipolleschi.png new file mode 100644 index 000000000..a90bec66e Binary files /dev/null and b/public/images/team/gh-cipolleschi.png differ diff --git a/public/images/team/gh-cortinico.jpg b/public/images/team/gh-cortinico.jpg new file mode 100644 index 000000000..e806a103b Binary files /dev/null and b/public/images/team/gh-cortinico.jpg differ diff --git a/public/images/team/gh-fbmal7.jpg b/public/images/team/gh-fbmal7.jpg new file mode 100644 index 000000000..0f79e181d Binary files /dev/null and b/public/images/team/gh-fbmal7.jpg differ diff --git a/public/images/team/gh-fkgozali.jpg b/public/images/team/gh-fkgozali.jpg new file mode 100644 index 000000000..9f87e7efb Binary files /dev/null and b/public/images/team/gh-fkgozali.jpg differ diff --git a/public/images/team/gh-huntie.jpg b/public/images/team/gh-huntie.jpg new file mode 100644 index 000000000..a4de75801 Binary files /dev/null and b/public/images/team/gh-huntie.jpg differ diff --git a/public/images/team/gh-javache.jpg b/public/images/team/gh-javache.jpg new file mode 100644 index 000000000..1f63907ea Binary files /dev/null and b/public/images/team/gh-javache.jpg differ diff --git a/public/images/team/gh-khalef1.jpg b/public/images/team/gh-khalef1.jpg new file mode 100644 index 000000000..94d96f670 Binary files /dev/null and b/public/images/team/gh-khalef1.jpg differ diff --git a/public/images/team/gh-kmagiera.jpg b/public/images/team/gh-kmagiera.jpg new file mode 100644 index 000000000..0e03ecb77 Binary files /dev/null and b/public/images/team/gh-kmagiera.jpg differ diff --git a/public/images/team/gh-motiz88.jpg b/public/images/team/gh-motiz88.jpg new file mode 100644 index 000000000..a67e30b1b Binary files /dev/null and b/public/images/team/gh-motiz88.jpg differ diff --git a/public/images/team/gh-rh389.jpg b/public/images/team/gh-rh389.jpg new file mode 100644 index 000000000..4d5a5e830 Binary files /dev/null and b/public/images/team/gh-rh389.jpg differ diff --git a/public/images/team/gh-rubennorte.jpg b/public/images/team/gh-rubennorte.jpg new file mode 100644 index 000000000..459c267e4 Binary files /dev/null and b/public/images/team/gh-rubennorte.jpg differ diff --git a/public/images/team/gh-samselikoff.jpg b/public/images/team/gh-samselikoff.jpg new file mode 100644 index 000000000..7887765b4 Binary files /dev/null and b/public/images/team/gh-samselikoff.jpg differ diff --git a/public/images/team/gh-simek.png b/public/images/team/gh-simek.png new file mode 100644 index 000000000..23a950103 Binary files /dev/null and b/public/images/team/gh-simek.png differ diff --git a/public/images/team/gh-stmoy.jpg b/public/images/team/gh-stmoy.jpg new file mode 100644 index 000000000..7694a7fb6 Binary files /dev/null and b/public/images/team/gh-stmoy.jpg differ diff --git a/public/images/team/gh-thymikee.jpg b/public/images/team/gh-thymikee.jpg new file mode 100644 index 000000000..d0debc5be Binary files /dev/null and b/public/images/team/gh-thymikee.jpg differ diff --git a/public/images/team/gh-vzaidman.jpg b/public/images/team/gh-vzaidman.jpg new file mode 100644 index 000000000..c76905615 Binary files /dev/null and b/public/images/team/gh-vzaidman.jpg differ diff --git a/public/images/team/jimmy-lai.jpg b/public/images/team/jimmy-lai.jpg new file mode 100644 index 000000000..57b50c800 Binary files /dev/null and b/public/images/team/jimmy-lai.jpg differ diff --git a/public/images/tutorial/codesandbox-devtools.png b/public/images/tutorial/codesandbox-devtools.png deleted file mode 100644 index 1f7ebd500..000000000 Binary files a/public/images/tutorial/codesandbox-devtools.png and /dev/null differ diff --git a/public/images/tutorial/components-tab.png b/public/images/tutorial/components-tab.png new file mode 100644 index 000000000..90ce0770e Binary files /dev/null and b/public/images/tutorial/components-tab.png differ diff --git a/public/images/tutorial/devtools-inspect.gif b/public/images/tutorial/devtools-inspect.gif new file mode 100644 index 000000000..5c623e6a7 Binary files /dev/null and b/public/images/tutorial/devtools-inspect.gif differ diff --git a/public/images/tutorial/devtools-select.gif b/public/images/tutorial/devtools-select.gif deleted file mode 100644 index dd1e1aa61..000000000 Binary files a/public/images/tutorial/devtools-select.gif and /dev/null differ diff --git a/public/images/tutorial/sandbox-new-tab.png b/public/images/tutorial/sandbox-new-tab.png new file mode 100644 index 000000000..093a363fb Binary files /dev/null and b/public/images/tutorial/sandbox-new-tab.png differ diff --git a/scripts/deadLinkChecker.js b/scripts/deadLinkChecker.js index 46a21cdc9..287dde36a 100644 --- a/scripts/deadLinkChecker.js +++ b/scripts/deadLinkChecker.js @@ -311,7 +311,7 @@ async function buildContributorMap() { async function fetchErrorCodes() { try { const response = await fetch( - 'https://raw.githubusercontent.com/facebook/react/main/scripts/error-codes/codes.json' + 'https://raw.githubusercontent.com/react/react/main/scripts/error-codes/codes.json' ); if (!response.ok) { throw new Error(`Failed to fetch error codes: ${response.status}`); diff --git a/scripts/generateOgImages.mjs b/scripts/generateOgImages.mjs new file mode 100644 index 000000000..937727a1c --- /dev/null +++ b/scripts/generateOgImages.mjs @@ -0,0 +1,219 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// Generates a static OG image for every content page, so social +// cards show the page title without any runtime image generation. +// Run after `next build` (see the `build` script in package.json). + +import fs from 'fs'; +import path from 'path'; +import satori from 'satori'; +import {Resvg} from '@resvg/resvg-js'; +import matter from 'gray-matter'; + +const ROOT = process.cwd(); +const CONTENT_DIR = path.join(ROOT, 'src', 'content'); +const OUT_DIR = path.join(ROOT, 'public', 'images', 'og'); +const CONCURRENCY = 8; + +const SECTION_LABELS = { + learn: 'Learn React', + reference: 'API Reference', + community: 'Community', + blog: 'Blog', +}; + +const bold = fs.readFileSync( + path.join(ROOT, 'public', 'fonts', 'Optimistic_Display_W_Bd.ttf') +); +const medium = fs.readFileSync( + path.join(ROOT, 'public', 'fonts', 'Optimistic_Display_W_Md.ttf') +); + +function el(type, style, children) { + return {type, props: {style, children}}; +} + +function card(title, pagePath) { + const section = pagePath.split('/')[1] ?? ''; + const label = SECTION_LABELS[section] ?? 'React'; + const logo = { + type: 'svg', + props: { + width: 80, + height: 72, + viewBox: '-10.5 -9.45 21 18.9', + fill: 'none', + children: [ + {type: 'circle', props: {cx: 0, cy: 0, r: 2, fill: '#58c4dc'}}, + { + type: 'g', + props: { + stroke: '#58c4dc', + strokeWidth: 1, + fill: 'none', + children: [ + {type: 'ellipse', props: {rx: 10, ry: 4.5}}, + { + type: 'ellipse', + props: {rx: 10, ry: 4.5, transform: 'rotate(60)'}, + }, + { + type: 'ellipse', + props: {rx: 10, ry: 4.5, transform: 'rotate(120)'}, + }, + ], + }, + }, + ], + }, + }; + return el( + 'div', + { + width: '100%', + height: '100%', + display: 'flex', + flexDirection: 'column', + padding: '72px 80px', + backgroundColor: '#23272f', + backgroundImage: + 'radial-gradient(circle at 25% 30%, #343a46 0%, #23272f 55%)', + }, + [ + el('div', {display: 'flex', alignItems: 'center', gap: '20px'}, [ + logo, + el( + 'div', + { + fontSize: 48, + fontFamily: 'Optimistic Display Bold', + color: '#f6f7f9', + }, + 'React' + ), + ]), + el( + 'div', + { + flexGrow: 1, + display: 'flex', + alignItems: 'center', + fontSize: title.length > 24 ? 72 : 96, + fontFamily: 'Optimistic Display Bold', + color: '#f6f7f9', + lineHeight: 1.1, + wordBreak: 'break-word', + }, + title + ), + el( + 'div', + { + fontSize: 40, + fontFamily: 'Optimistic Display Medium', + color: '#99a1b3', + }, + label + ), + ] + ); +} + +async function renderCard(title, pagePath) { + const svg = await satori(card(title, pagePath), { + width: 1200, + height: 630, + fonts: [ + { + name: 'Optimistic Display Bold', + data: bold, + weight: 700, + style: 'normal', + }, + { + name: 'Optimistic Display Medium', + data: medium, + weight: 500, + style: 'normal', + }, + ], + }); + return new Resvg(svg, {fitTo: {mode: 'width', value: 1200}}).render().asPng(); +} + +function collectSidebarTitles() { + const titles = new Map(); + for (const name of fs.readdirSync(path.join(ROOT, 'src'))) { + if (!/^sidebar.*\.json$/.test(name)) continue; + const walk = (node) => { + if (node.path && node.title) { + titles.set(node.path, node.title); + } + for (const child of node.routes ?? []) walk(child); + }; + walk(JSON.parse(fs.readFileSync(path.join(ROOT, 'src', name), 'utf8'))); + } + return titles; +} + +const sidebarTitles = collectSidebarTitles(); + +function collectPages(dir, out) { + for (const entry of fs.readdirSync(dir, {withFileTypes: true})) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + collectPages(full, out); + } else if (entry.name.endsWith('.md')) { + const rel = path.relative(CONTENT_DIR, full).replace(/\.md$/, ''); + const segments = rel.split(path.sep); + if (segments[segments.length - 1] === 'index') { + segments.pop(); + } + const pagePath = '/' + segments.join('/'); + if (pagePath === '/' || pagePath.startsWith('/errors')) { + continue; + } + const {data} = matter(fs.readFileSync(full, 'utf8')); + const title = data.title ?? sidebarTitles.get(pagePath); + if (title) { + out.push({title: String(title), pagePath}); + } + } + } + return out; +} + +export function ogImageFileName(pagePath) { + return pagePath.replace(/^\//, '').replace(/\//g, '-') + '.png'; +} + +async function main() { + const pages = collectPages(CONTENT_DIR, []); + fs.mkdirSync(OUT_DIR, {recursive: true}); + let done = 0; + const queue = [...pages]; + async function worker() { + for (;;) { + const page = queue.shift(); + if (!page) return; + const png = await renderCard(page.title, page.pagePath); + fs.writeFileSync(path.join(OUT_DIR, ogImageFileName(page.pagePath)), png); + done++; + if (done % 100 === 0) { + console.log(`og-images: ${done}/${pages.length}`); + } + } + } + await Promise.all(Array.from({length: CONCURRENCY}, worker)); + console.log(`og-images: generated ${done} images in public/images/og`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/src/components/ButtonLink.tsx b/src/components/ButtonLink.tsx index bd98d5b38..dff09ed3a 100644 --- a/src/components/ButtonLink.tsx +++ b/src/components/ButtonLink.tsx @@ -33,7 +33,7 @@ function ButtonLink({ className, 'active:scale-[.98] transition-transform inline-flex font-bold items-center outline-none focus:outline-none focus-visible:outline focus-visible:outline-link focus:outline-offset-2 focus-visible:dark:focus:outline-link-dark leading-snug', { - 'bg-link text-white dark:bg-brand-dark dark:text-secondary hover:bg-opacity-80': + 'bg-link text-white dark:bg-brand-dark dark:text-gray-90 hover:bg-opacity-80': type === 'primary', 'text-primary dark:text-primary-dark shadow-secondary-button-stroke dark:shadow-secondary-button-stroke-dark hover:bg-gray-40/5 active:bg-gray-40/10 hover:dark:bg-gray-60/5 active:dark:bg-gray-60/10': type === 'secondary', diff --git a/src/components/Layout/Footer.tsx b/src/components/Layout/Footer.tsx index 0b4e5ee25..22a8f0d9d 100644 --- a/src/components/Layout/Footer.tsx +++ b/src/components/Layout/Footer.tsx @@ -342,8 +342,13 @@ export function Footer() { <FooterLink href="/community" isHeader={true}> コミュニティ </FooterLink> +<<<<<<< HEAD <FooterLink href="https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md"> 行動規範 +======= + <FooterLink href="https://github.com/react/react/blob/main/CODE_OF_CONDUCT.md"> + Code of Conduct +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </FooterLink> <FooterLink href="/community/team">チーム紹介</FooterLink> <FooterLink href="/community/docs-contributors"> @@ -382,7 +387,7 @@ export function Footer() { </ExternalLink> <ExternalLink aria-label="React on Github" - href="https://github.com/facebook/react" + href="https://github.com/react/react" className={socialLinkClasses}> <IconGitHub /> </ExternalLink> diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index aa39fe5fc..59cf4386d 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -129,7 +129,18 @@ export function Page({ title={title} titleForTitleTag={meta.titleForTitleTag} isHomePage={isHomePage} - image={`/images/og-` + section + '.png'} + image={ + // OG images are generated per page at build time by + // scripts/generateOgImages.mjs. Pages without a generated + // card (home, errors, 404, 500) use the static section image. + isHomePage || + !title || + cleanedPath.startsWith('/errors') || + cleanedPath === '/404' || + cleanedPath === '/500' + ? `/images/og-${section ?? 'unknown'}.png` + : `/images/og/${cleanedPath.slice(1).replace(/\//g, '-')}.png` + } searchOrder={searchOrder} /> {(isHomePage || isBlogIndex) && ( diff --git a/src/components/Layout/Toc.tsx b/src/components/Layout/Toc.tsx index f91d96969..cc2c7295d 100644 --- a/src/components/Layout/Toc.tsx +++ b/src/components/Layout/Toc.tsx @@ -11,6 +11,7 @@ import cx from 'classnames'; import {useTocHighlight} from './useTocHighlight'; +import {IsInTocContext} from '../MDX/TocContext'; import type {Toc} from '../MDX/TocContext'; export function Toc({headings}: {headings: Toc}) { @@ -32,37 +33,39 @@ export function Toc({headings}: {headings: Toc}) { overscrollBehavior: 'contain', }}> <ul className="space-y-2 pb-16"> - {headings.length > 0 && - headings.map((h, i) => { - if (!h.url && process.env.NODE_ENV === 'development') { - console.error('Heading does not have URL'); - } - return ( - <li - key={`heading-${h.url}-${i}`} - className={cx( - 'text-sm px-2 rounded-s-xl', - selectedIndex === i - ? 'bg-highlight dark:bg-highlight-dark' - : null, - { - 'ps-4': h?.depth === 3, - hidden: h.depth && h.depth > 3, - } - )}> - <a + <IsInTocContext.Provider value={true}> + {headings.length > 0 && + headings.map((h, i) => { + if (!h.url && process.env.NODE_ENV === 'development') { + console.error('Heading does not have URL'); + } + return ( + <li + key={`heading-${h.url}-${i}`} className={cx( + 'text-sm px-2 rounded-s-xl', selectedIndex === i - ? 'text-link dark:text-link-dark font-bold' - : 'text-secondary dark:text-secondary-dark', - 'block hover:text-link dark:hover:text-link-dark leading-normal py-2' - )} - href={h.url}> - {h.text} - </a> - </li> - ); - })} + ? 'bg-highlight dark:bg-highlight-dark' + : null, + { + 'ps-4': h?.depth === 3, + hidden: h.depth && h.depth > 3, + } + )}> + <a + className={cx( + selectedIndex === i + ? 'text-link dark:text-link-dark font-bold' + : 'text-secondary dark:text-secondary-dark', + 'block hover:text-link dark:hover:text-link-dark leading-normal py-2' + )} + href={h.url}> + {h.text} + </a> + </li> + ); + })} + </IsInTocContext.Provider> </ul> </div> </nav> diff --git a/src/components/Layout/TopNav/TopNav.tsx b/src/components/Layout/TopNav/TopNav.tsx index efc90ed2c..37c2768a6 100644 --- a/src/components/Layout/TopNav/TopNav.tsx +++ b/src/components/Layout/TopNav/TopNav.tsx @@ -386,7 +386,7 @@ export default function TopNav({ </div> <div className="flex"> <Link - href="https://github.com/facebook/react/releases" + href="https://github.com/react/react/releases" target="_blank" rel="noreferrer noopener" aria-label="Open on GitHub" diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index 79154d8f7..79f399689 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -36,7 +36,7 @@ import YouWillLearnCard from './YouWillLearnCard'; import {Challenges, Hint, Solution} from './Challenges'; import {IconNavArrow} from '../Icon/IconNavArrow'; import ButtonLink from 'components/ButtonLink'; -import {TocContext} from './TocContext'; +import {TocContext, IsInTocContext} from './TocContext'; import type {Toc, TocItem} from './TocContext'; import {TeamMember} from './TeamMember'; import {LanguagesContext} from './LanguagesContext'; @@ -122,33 +122,57 @@ const RSC = ({children}: {children: React.ReactNode}) => ( <ExpandableCallout type="rsc">{children}</ExpandableCallout> ); -const CanaryBadge = ({title}: {title: string}) => ( - <span - title={title} - className={ - 'text-base font-display px-1 py-0.5 font-bold bg-gray-10 dark:bg-gray-60 text-gray-60 dark:text-gray-10 rounded' - }> - <IconCanary - size="s" - className={'inline me-1 mb-0.5 text-sm text-gray-60 dark:text-gray-10'} - /> - Canary only - </span> -); +const CanaryBadge = ({title}: {title: string}) => { + const isInToc = useContext(IsInTocContext); + if (isInToc) { + return ( + <IconCanary + size="s" + title={title} + className="inline me-1 mb-0.5 text-gray-60 dark:text-gray-10" + /> + ); + } + return ( + <span + title={title} + className={ + 'text-base font-display px-1 py-0.5 font-bold bg-gray-10 dark:bg-gray-60 text-gray-60 dark:text-gray-10 rounded' + }> + <IconCanary + size="s" + className={'inline me-1 mb-0.5 text-sm text-gray-60 dark:text-gray-10'} + /> + Canary only + </span> + ); +}; -const ExperimentalBadge = ({title}: {title: string}) => ( - <span - title={title} - className={ - 'text-base font-display px-1 py-0.5 font-bold bg-gray-10 dark:bg-gray-60 text-gray-60 dark:text-gray-10 rounded' - }> - <IconExperimental - size="s" - className={'inline me-1 mb-0.5 text-sm text-gray-60 dark:text-gray-10'} - /> - Experimental only - </span> -); +const ExperimentalBadge = ({title}: {title: string}) => { + const isInToc = useContext(IsInTocContext); + if (isInToc) { + return ( + <IconExperimental + size="s" + title={title} + className="inline me-1 mb-0.5 text-gray-60 dark:text-gray-10" + /> + ); + } + return ( + <span + title={title} + className={ + 'text-base font-display px-1 py-0.5 font-bold bg-gray-10 dark:bg-gray-60 text-gray-60 dark:text-gray-10 rounded' + }> + <IconExperimental + size="s" + className={'inline me-1 mb-0.5 text-sm text-gray-60 dark:text-gray-10'} + /> + Experimental only + </span> + ); +}; const NextMajorBadge = ({title}: {title: string}) => ( <span @@ -422,7 +446,11 @@ function InlineToc() { if (root.children.length < 2) { return null; } - return <InlineTocItem items={root.children} />; + return ( + <IsInTocContext.Provider value={true}> + <InlineTocItem items={root.children} /> + </IsInTocContext.Provider> + ); } function InlineTocItem({items}: {items: Array<NestedTocNode>}) { diff --git a/src/components/MDX/Sandpack/DownloadButton.tsx b/src/components/MDX/Sandpack/DownloadButton.tsx index b51627d89..cb5d4e842 100644 --- a/src/components/MDX/Sandpack/DownloadButton.tsx +++ b/src/components/MDX/Sandpack/DownloadButton.tsx @@ -19,7 +19,7 @@ let supportsImportMap = false; function subscribe(cb: () => void) { // This shouldn't actually need to update, but this works around - // https://github.com/facebook/react/issues/26095 + // https://github.com/react/react/issues/26095 let timeout = setTimeout(() => { supportsImportMap = (HTMLScriptElement as any).supports && diff --git a/src/components/MDX/TeamMember.tsx b/src/components/MDX/TeamMember.tsx index 2d0c65537..2716fa2d1 100644 --- a/src/components/MDX/TeamMember.tsx +++ b/src/components/MDX/TeamMember.tsx @@ -23,13 +23,49 @@ interface TeamMemberProps { name: string; title: string; permalink: string; - children: React.ReactNode; + children?: React.ReactNode; photo: string; twitter?: string; threads?: string; bsky?: string; github?: string; personal?: string; + // Comma-separated list of working groups. Suffix a group with `*` to mark + // that the member represents it on the Leadership Council, e.g. "Fiber*, DOM". + group?: string; +} + +function GroupBadges({group}: {group: string}) { + const groups = group + .split(',') + .map((g) => g.trim()) + .filter(Boolean); + if (groups.length === 0) { + return null; + } + return ( + <div className="flex flex-row flex-wrap gap-2 my-3"> + {groups.map((g) => { + const isLead = g.endsWith('*'); + const label = isLead ? g.slice(0, -1).trim() : g; + return ( + <span + key={g} + className="inline-flex items-center rounded-full bg-blue-10 dark:bg-gray-80 text-link dark:text-link-dark px-3 py-1 text-sm font-medium whitespace-nowrap"> + {label} + {isLead && ( + <span + className="ps-1 text-yellow-50" + aria-label="Leadership Council" + title="Leadership Council"> + ★ + </span> + )} + </span> + ); + })} + </div> + ); } // TODO: good alt text for images/links @@ -44,12 +80,11 @@ export function TeamMember({ threads, bsky, personal, + group, }: TeamMemberProps) { - if (name == null || title == null || permalink == null || children == null) { + if (name == null || title == null || permalink == null) { const identifier = name ?? title ?? permalink ?? 'unknown'; - throw new Error( - `Expected name, title, permalink, and children for ${identifier}` - ); + throw new Error(`Expected name, title, and permalink for ${identifier}`); } return ( <div className="pb-6 sm:pb-10"> @@ -69,6 +104,7 @@ export function TeamMember({ {name} </H3> {title && <div>{title}</div>} + {group && <GroupBadges group={group} />} {children} <div className="sm:flex sm:flex-row flex-wrap text-secondary dark:text-secondary-dark"> {twitter && ( diff --git a/src/components/MDX/TocContext.tsx b/src/components/MDX/TocContext.tsx index 924e6e09e..804895369 100644 --- a/src/components/MDX/TocContext.tsx +++ b/src/components/MDX/TocContext.tsx @@ -20,3 +20,6 @@ export type TocItem = { export type Toc = Array<TocItem>; export const TocContext = createContext<Toc>([]); + +// Lets badge components render compactly when inside the table of contents. +export const IsInTocContext = createContext(false); diff --git a/src/content/blog/2021/06/08/the-plan-for-react-18.md b/src/content/blog/2021/06/08/the-plan-for-react-18.md index 9e8a2d928..1a6163d25 100644 --- a/src/content/blog/2021/06/08/the-plan-for-react-18.md +++ b/src/content/blog/2021/06/08/the-plan-for-react-18.md @@ -51,7 +51,11 @@ React 18 へのアップグレードに関する詳細やリリースに関す 当初はワーキンググループ内部で一気に興味が高まることが予想されますので、招待されたメンバーのみがスレッドを作成したりコメントしたりできるようになっています。しかしスレッドは誰でも見えるようになっていますので、全員が同じ情報にアクセスできます。ワーキンググループのメンバーにとって生産的な環境を整えつつ、より広いコミュニティへの透明性も確保するという意味で、これが良い落とし所だと考えています。 +<<<<<<< HEAD もちろんこれまで通り、バグレポートや質問や一般的なフィードバックについては誰でも[イシュートラッカ](https://github.com/facebook/react/issues)に投稿することができます。 +======= +As always, you can submit bug reports, questions, and general feedback to our [issue tracker](https://github.com/react/react/issues). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ## React 18 アルファ版を今すぐ試す {/*how-to-try-react-18-alpha-today*/} diff --git a/src/content/blog/2022/03/08/react-18-upgrade-guide.md b/src/content/blog/2022/03/08/react-18-upgrade-guide.md index 8447a7624..8585dba19 100644 --- a/src/content/blog/2022/03/08/react-18-upgrade-guide.md +++ b/src/content/blog/2022/03/08/react-18-upgrade-guide.md @@ -13,7 +13,11 @@ March 08, 2022 by [Rick Hanlon](https://twitter.com/rickhanlonii) [リリース告知の記事](/blog/2022/03/29/react-v18)でお伝えしたとおり、React 18 には新たな並行レンダラを用いた機能が加わっており、既存のアプリケーションが段階的に採用できる方法も提供しています。この投稿では、React 18 にアップグレードするためのステップについてご案内します。 +<<<<<<< HEAD React 18 にアップグレードする際に遭遇した[問題は報告](https://github.com/facebook/react/issues/new/choose)をお願いします。 +======= +Please [report any issues](https://github.com/react/react/issues/new/choose) you encounter while upgrading to React 18. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Intro> @@ -315,11 +319,19 @@ Internet Explorer のサポートが必要な場合は、React 17 を使い続 ### React {/*react*/} +<<<<<<< HEAD * **コンポーネントが `undefined` を return できるように**:React はコンポーネントから `undefined` が返された場合でも警告しなくなりました。これにより、コンポーネントからの返り値として許される値が、コンポーネントツリーの中間で許可される値と合致するようになりました。JSX の前に `return` 文を書き忘れるといったミスを防ぐためには、リンタを使用することをお勧めします。 * **テストにおいて `act` 警告がオプトインに**:End-to-end のテストを実行している場合、`act` 警告は不要です。[オプトインする](https://github.com/reactwg/react-18/discussions/102)メカニズムを用意しましたので、それが有用であるユニットテストの場合にのみ有効化できるようになりました。 * **アンマウント済みコンポーネントにおける `setState` で警告を表示しないように**:これまで React は、`setState` がアンマウント済みのコンポーネントでコールされた場合、メモリリークに関する警告を表示してきました。この警告は購読に関する問題のために存在していましたが、state をセットしても問題ないシナリオでもこの警告にぶつかることが多く、また回避しようとした場合余計に悪いコードになってしまっていました。この警告は[削除](https://github.com/facebook/react/pull/22114)されました。 * **コンソールログの抑止を廃止**:strict モードを利用する場合、React はコンポーネントを 2 回レンダーして、予期しない副作用がないか見つけやすくします。React 17 では、ログが見やすくなるようにそのうちの 1 回ではコンソールログを抑止するようにしていました。これが混乱を招くという[コミュニティからのフィードバック](https://github.com/facebook/react/issues/21783)を受けて、このような抑止を行うことを止めました。代わりに、React DevTools をインストールしている場合は、2 回目のレンダーでのログはグレーで表示されるようになりました。完全に抑止するためのオプション(デフォルトではオフ)も存在します。 * **メモリ使用量の改善**:React はアンマウント時に内部のフィールドをより多く消去するようになったため、あなたのアプリに未修正のメモリリークがあった場合の悪影響が軽減されます。 +======= +* **Components can now render `undefined`:** React no longer warns if you return `undefined` from a component. This makes the allowed component return values consistent with values that are allowed in the middle of a component tree. We suggest to use a linter to prevent mistakes like forgetting a `return` statement before JSX. +* **In tests, `act` warnings are now opt-in:** If you're running end-to-end tests, the `act` warnings are unnecessary. We've introduced an [opt-in](https://github.com/reactwg/react-18/discussions/102) mechanism so you can enable them only for unit tests where they are useful and beneficial. +* **No warning about `setState` on unmounted components:** Previously, React warned about memory leaks when you call `setState` on an unmounted component. This warning was added for subscriptions, but people primarily run into it in scenarios where setting state is fine, and workarounds make the code worse. We've [removed](https://github.com/react/react/pull/22114) this warning. +* **No suppression of console logs:** When you use Strict Mode, React renders each component twice to help you find unexpected side effects. In React 17, we've suppressed console logs for one of the two renders to make the logs easier to read. In response to [community feedback](https://github.com/react/react/issues/21783) about this being confusing, we've removed the suppression. Instead, if you have React DevTools installed, the second log's renders will be displayed in grey, and there will be an option (off by default) to suppress them completely. +* **Improved memory usage:** React now cleans up more internal fields on unmount, making the impact from unfixed memory leaks that may exist in your application code less severe. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ### React DOM Server {/*react-dom-server*/} @@ -328,4 +340,8 @@ Internet Explorer のサポートが必要な場合は、React 17 を使い続 ## Changelog {/*changelog*/} +<<<<<<< HEAD [変更履歴の全リストはこちら](https://github.com/facebook/react/blob/main/CHANGELOG.md)を参照してください。 +======= +You can view the [full changelog here](https://github.com/react/react/blob/main/CHANGELOG.md). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca diff --git a/src/content/blog/2022/03/29/react-v18.md b/src/content/blog/2022/03/29/react-v18.md index b93e2208e..69c169368 100644 --- a/src/content/blog/2022/03/29/react-v18.md +++ b/src/content/blog/2022/03/29/react-v18.md @@ -270,75 +270,75 @@ React 18 の strict モードでは、開発時にコンポーネントがマウ ### React {/*react*/} -* Add `useTransition` and `useDeferredValue` to separate urgent updates from transitions. ([#10426](https://github.com/facebook/react/pull/10426), [#10715](https://github.com/facebook/react/pull/10715), [#15593](https://github.com/facebook/react/pull/15593), [#15272](https://github.com/facebook/react/pull/15272), [#15578](https://github.com/facebook/react/pull/15578), [#15769](https://github.com/facebook/react/pull/15769), [#17058](https://github.com/facebook/react/pull/17058), [#18796](https://github.com/facebook/react/pull/18796), [#19121](https://github.com/facebook/react/pull/19121), [#19703](https://github.com/facebook/react/pull/19703), [#19719](https://github.com/facebook/react/pull/19719), [#19724](https://github.com/facebook/react/pull/19724), [#20672](https://github.com/facebook/react/pull/20672), [#20976](https://github.com/facebook/react/pull/20976) by [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), [@rickhanlonii](https://github.com/rickhanlonii), and [@sebmarkbage](https://github.com/sebmarkbage)) -* Add `useId` for generating unique IDs. ([#17322](https://github.com/facebook/react/pull/17322), [#18576](https://github.com/facebook/react/pull/18576), [#22644](https://github.com/facebook/react/pull/22644), [#22672](https://github.com/facebook/react/pull/22672), [#21260](https://github.com/facebook/react/pull/21260) by [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), and [@sebmarkbage](https://github.com/sebmarkbage)) -* Add `useSyncExternalStore` to help external store libraries integrate with React. ([#15022](https://github.com/facebook/react/pull/15022), [#18000](https://github.com/facebook/react/pull/18000), [#18771](https://github.com/facebook/react/pull/18771), [#22211](https://github.com/facebook/react/pull/22211), [#22292](https://github.com/facebook/react/pull/22292), [#22239](https://github.com/facebook/react/pull/22239), [#22347](https://github.com/facebook/react/pull/22347), [#23150](https://github.com/facebook/react/pull/23150) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), and [@drarmstr](https://github.com/drarmstr)) -* Add `startTransition` as a version of `useTransition` without pending feedback. ([#19696](https://github.com/facebook/react/pull/19696) by [@rickhanlonii](https://github.com/rickhanlonii)) -* Add `useInsertionEffect` for CSS-in-JS libraries. ([#21913](https://github.com/facebook/react/pull/21913) by [@rickhanlonii](https://github.com/rickhanlonii)) -* Make Suspense remount layout effects when content reappears. ([#19322](https://github.com/facebook/react/pull/19322), [#19374](https://github.com/facebook/react/pull/19374), [#19523](https://github.com/facebook/react/pull/19523), [#20625](https://github.com/facebook/react/pull/20625), [#21079](https://github.com/facebook/react/pull/21079) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), and [@lunaruan](https://github.com/lunaruan)) -* Make `<StrictMode>` re-run effects to check for restorable state. ([#19523](https://github.com/facebook/react/pull/19523) , [#21418](https://github.com/facebook/react/pull/21418) by [@bvaughn](https://github.com/bvaughn) and [@lunaruan](https://github.com/lunaruan)) -* Assume Symbols are always available. ([#23348](https://github.com/facebook/react/pull/23348) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Remove `object-assign` polyfill. ([#23351](https://github.com/facebook/react/pull/23351) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Remove unsupported `unstable_changedBits` API. ([#20953](https://github.com/facebook/react/pull/20953) by [@acdlite](https://github.com/acdlite)) -* Allow components to render undefined. ([#21869](https://github.com/facebook/react/pull/21869) by [@rickhanlonii](https://github.com/rickhanlonii)) -* Flush `useEffect` resulting from discrete events like clicks synchronously. ([#21150](https://github.com/facebook/react/pull/21150) by [@acdlite](https://github.com/acdlite)) -* Suspense `fallback={undefined}` now behaves the same as `null` and isn't ignored. ([#21854](https://github.com/facebook/react/pull/21854) by [@rickhanlonii](https://github.com/rickhanlonii)) -* Consider all `lazy()` resolving to the same component equivalent. ([#20357](https://github.com/facebook/react/pull/20357) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Don't patch console during first render. ([#22308](https://github.com/facebook/react/pull/22308) by [@lunaruan](https://github.com/lunaruan)) -* Improve memory usage. ([#21039](https://github.com/facebook/react/pull/21039) by [@bgirard](https://github.com/bgirard)) -* Improve messages if string coercion throws (Temporal.*, Symbol, etc.) ([#22064](https://github.com/facebook/react/pull/22064) by [@justingrant](https://github.com/justingrant)) -* Use `setImmediate` when available over `MessageChannel`. ([#20834](https://github.com/facebook/react/pull/20834) by [@gaearon](https://github.com/gaearon)) -* Fix context failing to propagate inside suspended trees. ([#23095](https://github.com/facebook/react/pull/23095) by [@gaearon](https://github.com/gaearon)) -* Fix `useReducer` observing incorrect props by removing the eager bailout mechanism. ([#22445](https://github.com/facebook/react/pull/22445) by [@josephsavona](https://github.com/josephsavona)) -* Fix `setState` being ignored in Safari when appending iframes. ([#23111](https://github.com/facebook/react/pull/23111) by [@gaearon](https://github.com/gaearon)) -* Fix a crash when rendering `ZonedDateTime` in the tree. ([#20617](https://github.com/facebook/react/pull/20617) by [@dimaqq](https://github.com/dimaqq)) -* Fix a crash when document is set to `null` in tests. ([#22695](https://github.com/facebook/react/pull/22695) by [@SimenB](https://github.com/SimenB)) -* Fix `onLoad` not triggering when concurrent features are on. ([#23316](https://github.com/facebook/react/pull/23316) by [@gnoff](https://github.com/gnoff)) -* Fix a warning when a selector returns `NaN`. ([#23333](https://github.com/facebook/react/pull/23333) by [@hachibeeDI](https://github.com/hachibeeDI)) -* Fix a crash when document is set to `null` in tests. ([#22695](https://github.com/facebook/react/pull/22695) by [@SimenB](https://github.com/SimenB)) -* Fix the generated license header. ([#23004](https://github.com/facebook/react/pull/23004) by [@vitaliemiron](https://github.com/vitaliemiron)) -* Add `package.json` as one of the entry points. ([#22954](https://github.com/facebook/react/pull/22954) by [@Jack](https://github.com/Jack-Works)) -* Allow suspending outside a Suspense boundary. ([#23267](https://github.com/facebook/react/pull/23267) by [@acdlite](https://github.com/acdlite)) -* Log a recoverable error whenever hydration fails. ([#23319](https://github.com/facebook/react/pull/23319) by [@acdlite](https://github.com/acdlite)) +* Add `useTransition` and `useDeferredValue` to separate urgent updates from transitions. ([#10426](https://github.com/react/react/pull/10426), [#10715](https://github.com/react/react/pull/10715), [#15593](https://github.com/react/react/pull/15593), [#15272](https://github.com/react/react/pull/15272), [#15578](https://github.com/react/react/pull/15578), [#15769](https://github.com/react/react/pull/15769), [#17058](https://github.com/react/react/pull/17058), [#18796](https://github.com/react/react/pull/18796), [#19121](https://github.com/react/react/pull/19121), [#19703](https://github.com/react/react/pull/19703), [#19719](https://github.com/react/react/pull/19719), [#19724](https://github.com/react/react/pull/19724), [#20672](https://github.com/react/react/pull/20672), [#20976](https://github.com/react/react/pull/20976) by [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), [@rickhanlonii](https://github.com/rickhanlonii), and [@sebmarkbage](https://github.com/sebmarkbage)) +* Add `useId` for generating unique IDs. ([#17322](https://github.com/react/react/pull/17322), [#18576](https://github.com/react/react/pull/18576), [#22644](https://github.com/react/react/pull/22644), [#22672](https://github.com/react/react/pull/22672), [#21260](https://github.com/react/react/pull/21260) by [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), and [@sebmarkbage](https://github.com/sebmarkbage)) +* Add `useSyncExternalStore` to help external store libraries integrate with React. ([#15022](https://github.com/react/react/pull/15022), [#18000](https://github.com/react/react/pull/18000), [#18771](https://github.com/react/react/pull/18771), [#22211](https://github.com/react/react/pull/22211), [#22292](https://github.com/react/react/pull/22292), [#22239](https://github.com/react/react/pull/22239), [#22347](https://github.com/react/react/pull/22347), [#23150](https://github.com/react/react/pull/23150) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), and [@drarmstr](https://github.com/drarmstr)) +* Add `startTransition` as a version of `useTransition` without pending feedback. ([#19696](https://github.com/react/react/pull/19696) by [@rickhanlonii](https://github.com/rickhanlonii)) +* Add `useInsertionEffect` for CSS-in-JS libraries. ([#21913](https://github.com/react/react/pull/21913) by [@rickhanlonii](https://github.com/rickhanlonii)) +* Make Suspense remount layout effects when content reappears. ([#19322](https://github.com/react/react/pull/19322), [#19374](https://github.com/react/react/pull/19374), [#19523](https://github.com/react/react/pull/19523), [#20625](https://github.com/react/react/pull/20625), [#21079](https://github.com/react/react/pull/21079) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), and [@lunaruan](https://github.com/lunaruan)) +* Make `<StrictMode>` re-run effects to check for restorable state. ([#19523](https://github.com/react/react/pull/19523) , [#21418](https://github.com/react/react/pull/21418) by [@bvaughn](https://github.com/bvaughn) and [@lunaruan](https://github.com/lunaruan)) +* Assume Symbols are always available. ([#23348](https://github.com/react/react/pull/23348) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Remove `object-assign` polyfill. ([#23351](https://github.com/react/react/pull/23351) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Remove unsupported `unstable_changedBits` API. ([#20953](https://github.com/react/react/pull/20953) by [@acdlite](https://github.com/acdlite)) +* Allow components to render undefined. ([#21869](https://github.com/react/react/pull/21869) by [@rickhanlonii](https://github.com/rickhanlonii)) +* Flush `useEffect` resulting from discrete events like clicks synchronously. ([#21150](https://github.com/react/react/pull/21150) by [@acdlite](https://github.com/acdlite)) +* Suspense `fallback={undefined}` now behaves the same as `null` and isn't ignored. ([#21854](https://github.com/react/react/pull/21854) by [@rickhanlonii](https://github.com/rickhanlonii)) +* Consider all `lazy()` resolving to the same component equivalent. ([#20357](https://github.com/react/react/pull/20357) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Don't patch console during first render. ([#22308](https://github.com/react/react/pull/22308) by [@lunaruan](https://github.com/lunaruan)) +* Improve memory usage. ([#21039](https://github.com/react/react/pull/21039) by [@bgirard](https://github.com/bgirard)) +* Improve messages if string coercion throws (Temporal.*, Symbol, etc.) ([#22064](https://github.com/react/react/pull/22064) by [@justingrant](https://github.com/justingrant)) +* Use `setImmediate` when available over `MessageChannel`. ([#20834](https://github.com/react/react/pull/20834) by [@gaearon](https://github.com/gaearon)) +* Fix context failing to propagate inside suspended trees. ([#23095](https://github.com/react/react/pull/23095) by [@gaearon](https://github.com/gaearon)) +* Fix `useReducer` observing incorrect props by removing the eager bailout mechanism. ([#22445](https://github.com/react/react/pull/22445) by [@josephsavona](https://github.com/josephsavona)) +* Fix `setState` being ignored in Safari when appending iframes. ([#23111](https://github.com/react/react/pull/23111) by [@gaearon](https://github.com/gaearon)) +* Fix a crash when rendering `ZonedDateTime` in the tree. ([#20617](https://github.com/react/react/pull/20617) by [@dimaqq](https://github.com/dimaqq)) +* Fix a crash when document is set to `null` in tests. ([#22695](https://github.com/react/react/pull/22695) by [@SimenB](https://github.com/SimenB)) +* Fix `onLoad` not triggering when concurrent features are on. ([#23316](https://github.com/react/react/pull/23316) by [@gnoff](https://github.com/gnoff)) +* Fix a warning when a selector returns `NaN`. ([#23333](https://github.com/react/react/pull/23333) by [@hachibeeDI](https://github.com/hachibeeDI)) +* Fix a crash when document is set to `null` in tests. ([#22695](https://github.com/react/react/pull/22695) by [@SimenB](https://github.com/SimenB)) +* Fix the generated license header. ([#23004](https://github.com/react/react/pull/23004) by [@vitaliemiron](https://github.com/vitaliemiron)) +* Add `package.json` as one of the entry points. ([#22954](https://github.com/react/react/pull/22954) by [@Jack](https://github.com/Jack-Works)) +* Allow suspending outside a Suspense boundary. ([#23267](https://github.com/react/react/pull/23267) by [@acdlite](https://github.com/acdlite)) +* Log a recoverable error whenever hydration fails. ([#23319](https://github.com/react/react/pull/23319) by [@acdlite](https://github.com/acdlite)) ### React DOM {/*react-dom*/} -* Add `createRoot` and `hydrateRoot`. ([#10239](https://github.com/facebook/react/pull/10239), [#11225](https://github.com/facebook/react/pull/11225), [#12117](https://github.com/facebook/react/pull/12117), [#13732](https://github.com/facebook/react/pull/13732), [#15502](https://github.com/facebook/react/pull/15502), [#15532](https://github.com/facebook/react/pull/15532), [#17035](https://github.com/facebook/react/pull/17035), [#17165](https://github.com/facebook/react/pull/17165), [#20669](https://github.com/facebook/react/pull/20669), [#20748](https://github.com/facebook/react/pull/20748), [#20888](https://github.com/facebook/react/pull/20888), [#21072](https://github.com/facebook/react/pull/21072), [#21417](https://github.com/facebook/react/pull/21417), [#21652](https://github.com/facebook/react/pull/21652), [#21687](https://github.com/facebook/react/pull/21687), [#23207](https://github.com/facebook/react/pull/23207), [#23385](https://github.com/facebook/react/pull/23385) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), [@gaearon](https://github.com/gaearon), [@lunaruan](https://github.com/lunaruan), [@rickhanlonii](https://github.com/rickhanlonii), [@trueadm](https://github.com/trueadm), and [@sebmarkbage](https://github.com/sebmarkbage)) -* Add selective hydration. ([#14717](https://github.com/facebook/react/pull/14717), [#14884](https://github.com/facebook/react/pull/14884), [#16725](https://github.com/facebook/react/pull/16725), [#16880](https://github.com/facebook/react/pull/16880), [#17004](https://github.com/facebook/react/pull/17004), [#22416](https://github.com/facebook/react/pull/22416), [#22629](https://github.com/facebook/react/pull/22629), [#22448](https://github.com/facebook/react/pull/22448), [#22856](https://github.com/facebook/react/pull/22856), [#23176](https://github.com/facebook/react/pull/23176) by [@acdlite](https://github.com/acdlite), [@gaearon](https://github.com/gaearon), [@salazarm](https://github.com/salazarm), and [@sebmarkbage](https://github.com/sebmarkbage)) -* Add `aria-description` to the list of known ARIA attributes. ([#22142](https://github.com/facebook/react/pull/22142) by [@mahyareb](https://github.com/mahyareb)) -* Add `onResize` event to video elements. ([#21973](https://github.com/facebook/react/pull/21973) by [@rileyjshaw](https://github.com/rileyjshaw)) -* Add `imageSizes` and `imageSrcSet` to known props. ([#22550](https://github.com/facebook/react/pull/22550) by [@eps1lon](https://github.com/eps1lon)) -* Allow non-string `<option>` children if `value` is provided. ([#21431](https://github.com/facebook/react/pull/21431) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Fix `aspectRatio` style not being applied. ([#21100](https://github.com/facebook/react/pull/21100) by [@gaearon](https://github.com/gaearon)) -* Warn if `renderSubtreeIntoContainer` is called. ([#23355](https://github.com/facebook/react/pull/23355) by [@acdlite](https://github.com/acdlite)) +* Add `createRoot` and `hydrateRoot`. ([#10239](https://github.com/react/react/pull/10239), [#11225](https://github.com/react/react/pull/11225), [#12117](https://github.com/react/react/pull/12117), [#13732](https://github.com/react/react/pull/13732), [#15502](https://github.com/react/react/pull/15502), [#15532](https://github.com/react/react/pull/15532), [#17035](https://github.com/react/react/pull/17035), [#17165](https://github.com/react/react/pull/17165), [#20669](https://github.com/react/react/pull/20669), [#20748](https://github.com/react/react/pull/20748), [#20888](https://github.com/react/react/pull/20888), [#21072](https://github.com/react/react/pull/21072), [#21417](https://github.com/react/react/pull/21417), [#21652](https://github.com/react/react/pull/21652), [#21687](https://github.com/react/react/pull/21687), [#23207](https://github.com/react/react/pull/23207), [#23385](https://github.com/react/react/pull/23385) by [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), [@gaearon](https://github.com/gaearon), [@lunaruan](https://github.com/lunaruan), [@rickhanlonii](https://github.com/rickhanlonii), [@trueadm](https://github.com/trueadm), and [@sebmarkbage](https://github.com/sebmarkbage)) +* Add selective hydration. ([#14717](https://github.com/react/react/pull/14717), [#14884](https://github.com/react/react/pull/14884), [#16725](https://github.com/react/react/pull/16725), [#16880](https://github.com/react/react/pull/16880), [#17004](https://github.com/react/react/pull/17004), [#22416](https://github.com/react/react/pull/22416), [#22629](https://github.com/react/react/pull/22629), [#22448](https://github.com/react/react/pull/22448), [#22856](https://github.com/react/react/pull/22856), [#23176](https://github.com/react/react/pull/23176) by [@acdlite](https://github.com/acdlite), [@gaearon](https://github.com/gaearon), [@salazarm](https://github.com/salazarm), and [@sebmarkbage](https://github.com/sebmarkbage)) +* Add `aria-description` to the list of known ARIA attributes. ([#22142](https://github.com/react/react/pull/22142) by [@mahyareb](https://github.com/mahyareb)) +* Add `onResize` event to video elements. ([#21973](https://github.com/react/react/pull/21973) by [@rileyjshaw](https://github.com/rileyjshaw)) +* Add `imageSizes` and `imageSrcSet` to known props. ([#22550](https://github.com/react/react/pull/22550) by [@eps1lon](https://github.com/eps1lon)) +* Allow non-string `<option>` children if `value` is provided. ([#21431](https://github.com/react/react/pull/21431) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Fix `aspectRatio` style not being applied. ([#21100](https://github.com/react/react/pull/21100) by [@gaearon](https://github.com/gaearon)) +* Warn if `renderSubtreeIntoContainer` is called. ([#23355](https://github.com/react/react/pull/23355) by [@acdlite](https://github.com/acdlite)) ### React DOM Server {/*react-dom-server-1*/} -* Add the new streaming renderer. ([#14144](https://github.com/facebook/react/pull/14144), [#20970](https://github.com/facebook/react/pull/20970), [#21056](https://github.com/facebook/react/pull/21056), [#21255](https://github.com/facebook/react/pull/21255), [#21200](https://github.com/facebook/react/pull/21200), [#21257](https://github.com/facebook/react/pull/21257), [#21276](https://github.com/facebook/react/pull/21276), [#22443](https://github.com/facebook/react/pull/22443), [#22450](https://github.com/facebook/react/pull/22450), [#23247](https://github.com/facebook/react/pull/23247), [#24025](https://github.com/facebook/react/pull/24025), [#24030](https://github.com/facebook/react/pull/24030) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Fix context providers in SSR when handling multiple requests. ([#23171](https://github.com/facebook/react/pull/23171) by [@frandiox](https://github.com/frandiox)) -* Revert to client render on text mismatch. ([#23354](https://github.com/facebook/react/pull/23354) by [@acdlite](https://github.com/acdlite)) -* Deprecate `renderToNodeStream`. ([#23359](https://github.com/facebook/react/pull/23359) by [@sebmarkbage](https://github.com/sebmarkbage)) -* Fix a spurious error log in the new server renderer. ([#24043](https://github.com/facebook/react/pull/24043) by [@eps1lon](https://github.com/eps1lon)) -* Fix a bug in the new server renderer. ([#22617](https://github.com/facebook/react/pull/22617) by [@shuding](https://github.com/shuding)) -* Ignore function and symbol values inside custom elements on the server. ([#21157](https://github.com/facebook/react/pull/21157) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Add the new streaming renderer. ([#14144](https://github.com/react/react/pull/14144), [#20970](https://github.com/react/react/pull/20970), [#21056](https://github.com/react/react/pull/21056), [#21255](https://github.com/react/react/pull/21255), [#21200](https://github.com/react/react/pull/21200), [#21257](https://github.com/react/react/pull/21257), [#21276](https://github.com/react/react/pull/21276), [#22443](https://github.com/react/react/pull/22443), [#22450](https://github.com/react/react/pull/22450), [#23247](https://github.com/react/react/pull/23247), [#24025](https://github.com/react/react/pull/24025), [#24030](https://github.com/react/react/pull/24030) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Fix context providers in SSR when handling multiple requests. ([#23171](https://github.com/react/react/pull/23171) by [@frandiox](https://github.com/frandiox)) +* Revert to client render on text mismatch. ([#23354](https://github.com/react/react/pull/23354) by [@acdlite](https://github.com/acdlite)) +* Deprecate `renderToNodeStream`. ([#23359](https://github.com/react/react/pull/23359) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Fix a spurious error log in the new server renderer. ([#24043](https://github.com/react/react/pull/24043) by [@eps1lon](https://github.com/eps1lon)) +* Fix a bug in the new server renderer. ([#22617](https://github.com/react/react/pull/22617) by [@shuding](https://github.com/shuding)) +* Ignore function and symbol values inside custom elements on the server. ([#21157](https://github.com/react/react/pull/21157) by [@sebmarkbage](https://github.com/sebmarkbage)) ### React DOM Test Utils {/*react-dom-test-utils*/} -* Throw when `act` is used in production. ([#21686](https://github.com/facebook/react/pull/21686) by [@acdlite](https://github.com/acdlite)) -* Support disabling spurious act warnings with `global.IS_REACT_ACT_ENVIRONMENT`. ([#22561](https://github.com/facebook/react/pull/22561) by [@acdlite](https://github.com/acdlite)) -* Expand act warning to cover all APIs that might schedule React work. ([#22607](https://github.com/facebook/react/pull/22607) by [@acdlite](https://github.com/acdlite)) -* Make `act` batch updates. ([#21797](https://github.com/facebook/react/pull/21797) by [@acdlite](https://github.com/acdlite)) -* Remove warning for dangling passive effects. ([#22609](https://github.com/facebook/react/pull/22609) by [@acdlite](https://github.com/acdlite)) +* Throw when `act` is used in production. ([#21686](https://github.com/react/react/pull/21686) by [@acdlite](https://github.com/acdlite)) +* Support disabling spurious act warnings with `global.IS_REACT_ACT_ENVIRONMENT`. ([#22561](https://github.com/react/react/pull/22561) by [@acdlite](https://github.com/acdlite)) +* Expand act warning to cover all APIs that might schedule React work. ([#22607](https://github.com/react/react/pull/22607) by [@acdlite](https://github.com/acdlite)) +* Make `act` batch updates. ([#21797](https://github.com/react/react/pull/21797) by [@acdlite](https://github.com/acdlite)) +* Remove warning for dangling passive effects. ([#22609](https://github.com/react/react/pull/22609) by [@acdlite](https://github.com/acdlite)) ### React Refresh {/*react-refresh*/} -* Track late-mounted roots in Fast Refresh. ([#22740](https://github.com/facebook/react/pull/22740) by [@anc95](https://github.com/anc95)) -* Add `exports` field to `package.json`. ([#23087](https://github.com/facebook/react/pull/23087) by [@otakustay](https://github.com/otakustay)) +* Track late-mounted roots in Fast Refresh. ([#22740](https://github.com/react/react/pull/22740) by [@anc95](https://github.com/anc95)) +* Add `exports` field to `package.json`. ([#23087](https://github.com/react/react/pull/23087) by [@otakustay](https://github.com/otakustay)) ### Server Components (Experimental) {/*server-components-experimental*/} -* Add Server Context support. ([#23244](https://github.com/facebook/react/pull/23244) by [@salazarm](https://github.com/salazarm)) -* Add `lazy` support. ([#24068](https://github.com/facebook/react/pull/24068) by [@gnoff](https://github.com/gnoff)) -* Update webpack plugin for webpack 5 ([#22739](https://github.com/facebook/react/pull/22739) by [@michenly](https://github.com/michenly)) -* Fix a mistake in the Node loader. ([#22537](https://github.com/facebook/react/pull/22537) by [@btea](https://github.com/btea)) -* Use `globalThis` instead of `window` for edge environments. ([#22777](https://github.com/facebook/react/pull/22777) by [@huozhi](https://github.com/huozhi)) +* Add Server Context support. ([#23244](https://github.com/react/react/pull/23244) by [@salazarm](https://github.com/salazarm)) +* Add `lazy` support. ([#24068](https://github.com/react/react/pull/24068) by [@gnoff](https://github.com/gnoff)) +* Update webpack plugin for webpack 5 ([#22739](https://github.com/react/react/pull/22739) by [@michenly](https://github.com/michenly)) +* Fix a mistake in the Node loader. ([#22537](https://github.com/react/react/pull/22537) by [@btea](https://github.com/btea)) +* Use `globalThis` instead of `window` for edge environments. ([#22777](https://github.com/react/react/pull/22777) by [@huozhi](https://github.com/huozhi)) diff --git a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md index 2ed270aba..aa77e9bb9 100644 --- a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md +++ b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md @@ -69,7 +69,11 @@ React Conf 2021 において、React Forget についての[アーリープレ 我々は、文脈なしに個々の遅いコミットやコンポーネントに関する情報だけ分かったところで開発者にとってはさほど役立たない、ということを学びました。知りたい情報は、現に遅いコミットになってしまっている理由の方です。開発者は、ボタンクリック、初回ロード、ページ移動といった特定の操作を追跡してパフォーマンスの悪化を監視し、なぜ操作が遅かったのか、どのように修正するのかを知りたいのです。 +<<<<<<< HEAD この問題を解決するために、以前 [Interaction Tracing API](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16) の作成を試みたことがありますが、これには根本的な設計の問題があったため、操作が遅い理由を正確に知ることが難しく、場合によっては操作が全く終わらなくなってしまうこともありました。このため[この API は削除](https://github.com/facebook/react/pull/20037)せざるを得ませんでした。 +======= +We previously tried to solve this issue by creating an [Interaction Tracing API](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16), but it had some fundamental design flaws that reduced the accuracy of tracking why an interaction was slow and sometimes resulted in interactions never ending. We ended up [removing this API](https://github.com/react/react/pull/20037) because of these issues. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca 現在、この問題を解決するための Interaction Tracing API の新バージョン(`startTransition` で起動するので Transition Tracing と仮に呼んでいます)に取り組んでいます。 diff --git a/src/content/blog/2024/04/25/react-19-upgrade-guide.md b/src/content/blog/2024/04/25/react-19-upgrade-guide.md index 4505c79ec..1e4734864 100644 --- a/src/content/blog/2024/04/25/react-19-upgrade-guide.md +++ b/src/content/blog/2024/04/25/react-19-upgrade-guide.md @@ -24,7 +24,11 @@ React 19 へのアップグレードを容易にするため、`react@18.3` リ React 19 にアップグレードする前に、問題点を見つけるためにまず React 18.3 にアップグレードすることをお勧めします。 +<<<<<<< HEAD 18.3 における変更点については、[リリースノート](https://github.com/facebook/react/blob/main/CHANGELOG.md#1830-april-25-2024)をご覧ください。 +======= +For a list of changes in 18.3 see the [Release Notes](https://github.com/react/react/blob/main/CHANGELOG.md#1830-april-25-2024). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> @@ -38,7 +42,11 @@ React 19 にアップグレードする前に、問題点を見つけるため - [TypeScript 関連の変更](#typescript-changes) - [Changelog](#changelog) +<<<<<<< HEAD React 19 をテストしていただける方は、このアップグレードガイドに従い、遭遇した[問題を報告](https://github.com/facebook/react/issues/new?assignees=&labels=React+19&projects=&template=19.md&title=%5BReact+19%5D)してください。React 19 に追加された新機能のリストについては、[React 19 リリースのお知らせ](/blog/2024/12/05/react-19)をご覧ください。 +======= +If you'd like to help us test React 19, follow the steps in this upgrade guide and [report any issues](https://github.com/react/react/issues/new?assignees=&labels=React+19&projects=&template=19.md&title=%5BReact+19%5D) you encounter. For a list of new features added to React 19, see the [React 19 release post](/blog/2024/12/05/react-19). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- ## インストール {/*installing*/} @@ -256,7 +264,11 @@ class Child extends React.Component { #### 削除:文字列形式の ref {/*removed-string-refs*/} 文字列形式の ref は [2018 年 3 月 (v16.3.0)](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html) に非推奨化されました。 +<<<<<<< HEAD [いくつかの問題](https://github.com/facebook/react/issues/1373)のためコールバック形式の ref に置き換えられるまで、クラスコンポーネントは文字列形式の ref をサポートしていました。React 19 では、React をよりシンプルで理解しやすくするため、文字列形式の ref を削除します。 +======= +Class components supported string refs before being replaced by ref callbacks due to [multiple downsides](https://github.com/react/react/issues/1373). In React 19, we're removing string refs to make React simpler and easier to understand. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca クラスコンポーネントでまだ文字列形式の ref を使用している場合は、コールバック形式の ref に移行する必要があります。 @@ -730,6 +742,7 @@ const reducer = (state: State, action: Action) => state; ### その他の破壊的変更 {/*other-breaking-changes*/} +<<<<<<< HEAD - **react-dom**: `src` と `href での JavaScript URL に対するエラー [#26507](https://github.com/facebook/react/pull/26507) - **react-dom**: `onRecoverableError` から `errorInfo.digest` を削除 [#28222](https://github.com/facebook/react/pull/28222) - **react-dom**: `unstable_flushControlled` を削除 [#26397](https://github.com/facebook/react/pull/26397) @@ -737,9 +750,19 @@ const reducer = (state: State, action: Action) => state; - **react-dom**: `unstable_renderSubtreeIntoContainer` を削除 [#28271](https://github.com/facebook/react/pull/28271) - **react-dom**: `unstable_runWithPriority` を削除 [#28271](https://github.com/facebook/react/pull/28271) - **react-is**: `react-is` から非推奨のメソッドを削除 [28224](https://github.com/facebook/react/pull/28224) +======= +- **react-dom**: Error for javascript URLs in `src` and `href` [#26507](https://github.com/react/react/pull/26507) +- **react-dom**: Remove `errorInfo.digest` from `onRecoverableError` [#28222](https://github.com/react/react/pull/28222) +- **react-dom**: Remove `unstable_flushControlled` [#26397](https://github.com/react/react/pull/26397) +- **react-dom**: Remove `unstable_createEventHandle` [#28271](https://github.com/react/react/pull/28271) +- **react-dom**: Remove `unstable_renderSubtreeIntoContainer` [#28271](https://github.com/react/react/pull/28271) +- **react-dom**: Remove `unstable_runWithPriority` [#28271](https://github.com/react/react/pull/28271) +- **react-is**: Remove deprecated methods from `react-is` [28224](https://github.com/react/react/pull/28224) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ### その他の注目すべき変更点 {/*other-notable-changes*/} +<<<<<<< HEAD - **react**: 同期・デフォルト・連続レーンのバッチ処理 [#25700](https://github.com/facebook/react/pull/25700) - **react**: サスペンドされたコンポーネントの兄弟を事前レンダーしない [#26380](https://github.com/facebook/react/pull/26380) - **react**: レンダーフェーズでの更新によって引き起こされる無限更新ループを検出 [#26625](https://github.com/facebook/react/pull/26625) @@ -748,6 +771,16 @@ const reducer = (state: State, action: Action) => state; - **react-dom**: src/href に空文字列を設定しないよう警告(アンカータグを除く)[#28124](https://github.com/facebook/react/pull/28124) 全変更点のリストについては、[Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1900-december-5-2024) を参照してください。 +======= +- **react**: Batch sync, default and continuous lanes [#25700](https://github.com/react/react/pull/25700) +- **react**: Don't prerender siblings of suspended component [#26380](https://github.com/react/react/pull/26380) +- **react**: Detect infinite update loops caused by render phase updates [#26625](https://github.com/react/react/pull/26625) +- **react-dom**: Transitions in popstate are now synchronous [#26025](https://github.com/react/react/pull/26025) +- **react-dom**: Remove layout effect warning during SSR [#26395](https://github.com/react/react/pull/26395) +- **react-dom**: Warn and don’t set empty string for src/href (except anchor tags) [#28124](https://github.com/react/react/pull/28124) + +For a full list of changes, please see the [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md#1900-december-5-2024). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- diff --git a/src/content/blog/2024/05/22/react-conf-2024-recap.md b/src/content/blog/2024/05/22/react-conf-2024-recap.md index cfc8baa8a..c839e3c92 100644 --- a/src/content/blog/2024/05/22/react-conf-2024-recap.md +++ b/src/content/blog/2024/05/22/react-conf-2024-recap.md @@ -45,7 +45,11 @@ _[1 日目の全ストリームはこちらから視聴できます。](https:// - [React for Two Computers](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=18825s) by [Dan Abramov](https://bsky.app/profile/danabra.mov) - [And Now You Understand React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY&t=11256s) by [Kent C. Dodds](https://twitter.com/kentcdodds) +<<<<<<< HEAD 基調講演の締めくくりとして、[Joe Savona](https://twitter.com/en_JS)、[Sathya Gunasekaran](https://twitter.com/_gsathya)、[Mofei Zhang](https://twitter.com/zmofei) が、React Compiler が[オープンソース](https://github.com/facebook/react/pull/29061)化されたことを発表し、React Compiler の実験バージョンを共有しました。 +======= +Finally, we ended the keynote with [Joe Savona](https://twitter.com/en_JS), [Sathya Gunasekaran](https://twitter.com/_gsathya), and [Mofei Zhang](https://twitter.com/zmofei) announcing that the React Compiler is now [Open Source](https://github.com/react/react/pull/29061), and sharing an experimental version of the React Compiler to try out. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca コンパイラの使用方法や動作についての詳細は、[ドキュメント](/learn/react-compiler)および以下の講演をご覧ください。 diff --git a/src/content/blog/2024/10/21/react-compiler-beta-release.md b/src/content/blog/2024/10/21/react-compiler-beta-release.md index 8040b31be..aedb59396 100644 --- a/src/content/blog/2024/10/21/react-compiler-beta-release.md +++ b/src/content/blog/2024/10/21/react-compiler-beta-release.md @@ -92,7 +92,11 @@ React Compiler はライブラリのコンパイルにも使用できます。Re 以前 React Conf にて、招待制の [React Compiler Working Group](https://github.com/reactwg/react-compiler) を発表し、コンパイラの実験的リリースに対するフィードバックを提供し、質問をし、貢献を行える場として利用してきました。 +<<<<<<< HEAD 本日より、React Compiler Beta のリリースに合わせ、Working Group のメンバーシップを全員に開放します。React Compiler Working Group の目標は、エコシステム全体で、既存のアプリケーションやライブラリによる React Compiler のスムーズかつ段階的な採用準備を整えることです。今後もバグ報告は [React リポジトリ](https://github.com/facebook/react)に行っていただく一方で、フィードバックや質問、アイディアの共有は、[Working Group のディスカッションフォーラム](https://github.com/reactwg/react-compiler/discussions)を利用してください。 +======= +From today, together with the Beta release of React Compiler, we are opening up Working Group membership to everyone. The goal of the React Compiler Working Group is to prepare the ecosystem for a smooth, gradual adoption of React Compiler by existing applications and libraries. Please continue to file bug reports in the [React repo](https://github.com/react/react), but please leave feedback, ask questions, or share ideas in the [Working Group discussion forum](https://github.com/reactwg/react-compiler/discussions). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca コアチームも研究結果を共有にディスカッションリポジトリを使用します。安定版リリースが近づくにつれ、重要な情報もこのフォーラムに投稿されます。 @@ -127,7 +131,11 @@ React Compiler はライブラリのコンパイルにも使用できます。Re --- +<<<<<<< HEAD [^1]: コンパイラの貢献に協力いただいた [@nikeee](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Anikeee)、[@henryqdineen](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Ahenryqdineen)、[@TrickyPi](https://github.com/facebook/react/pulls?q=is%3Apr+author%3ATrickyPi) に感謝します。 +======= +[^1]: Thanks [@nikeee](https://github.com/react/react/pulls?q=is%3Apr+author%3Anikeee), [@henryqdineen](https://github.com/react/react/pulls?q=is%3Apr+author%3Ahenryqdineen), [@TrickyPi](https://github.com/react/react/pulls?q=is%3Apr+author%3ATrickyPi), and several others for their contributions to the compiler. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca [^2]: Meta での React コンパイラに関する本研究を主導し、この投稿をレビューしていただいた [Vaishali Garg](https://www.linkedin.com/in/vaishaligarg09) に感謝します。 diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md index ae809ef00..1158ac983 100644 --- a/src/content/blog/2024/12/05/react-19.md +++ b/src/content/blog/2024/12/05/react-19.md @@ -182,7 +182,11 @@ const [error, submitAction, isPending] = useActionState( `React.useActionState` は以前の Canary リリースでは `ReactDOM.useFormState` と呼ばれていましたが、名前を変更し、`useFormState` を非推奨にしました。 +<<<<<<< HEAD 詳細は [#28491](https://github.com/facebook/react/pull/28491) を参照してください。 +======= +See [#28491](https://github.com/react/react/pull/28491) for more info. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md index 91e949992..ad55ee548 100644 --- a/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md +++ b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md @@ -11458,7 +11458,11 @@ root.render( これらがどのように機能するかについてもっと知りたい場合は、ドキュメントで [`<ViewTransition>` の動作の仕組み](/reference/react/ViewTransition#how-does-viewtransition-work)をチェックしてください。 +<<<<<<< HEAD _ビュー遷移機能の開発経緯についての詳細は、[@sebmarkbage](https://twitter.com/sebmarkbage) による [#31975](https://github.com/facebook/react/pull/31975)、[#32105](https://github.com/facebook/react/pull/32105)、[#32041](https://github.com/facebook/react/pull/32041)、[#32734](https://github.com/facebook/react/pull/32734)、[#32797](https://github.com/facebook/react/pull/32797)、[#31999](https://github.com/facebook/react/pull/31999)、[#32031](https://github.com/facebook/react/pull/32031)、[#32050](https://github.com/facebook/react/pull/32050)、[#32820](https://github.com/facebook/react/pull/32820)、[#32029](https://github.com/facebook/react/pull/32029)、[#32028](https://github.com/facebook/react/pull/32028)、および [#32038](https://github.com/facebook/react/pull/32038) を参照してください (thanks Seb!)。_ +======= +_For more background on how we built View Transitions, see: [#31975](https://github.com/react/react/pull/31975), [#32105](https://github.com/react/react/pull/32105), [#32041](https://github.com/react/react/pull/32041), [#32734](https://github.com/react/react/pull/32734), [#32797](https://github.com/react/react/pull/32797) [#31999](https://github.com/react/react/pull/31999), [#32031](https://github.com/react/react/pull/32031), [#32050](https://github.com/react/react/pull/32050), [#32820](https://github.com/react/react/pull/32820), [#32029](https://github.com/react/react/pull/32029), [#32028](https://github.com/react/react/pull/32028), and [#32038](https://github.com/react/react/pull/32038) by [@sebmarkbage](https://twitter.com/sebmarkbage) (thanks Seb!)._ +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- diff --git a/src/content/blog/2025/10/01/react-19-2.md b/src/content/blog/2025/10/01/react-19-2.md index ec4ec8233..d3c836b43 100644 --- a/src/content/blog/2025/10/01/react-19-2.md +++ b/src/content/blog/2025/10/01/react-19-2.md @@ -300,7 +300,11 @@ Node.js 環境では、引き続き Node ストリーム API の使用を強く コンパイラ対応のルールの完全なリストについては、[リンタのドキュメントを確認してください](/reference/eslint-plugin-react-hooks#recommended)。 +<<<<<<< HEAD 変更の完全なリストについては、`eslint-plugin-react-hooks` の [changelog を確認してください](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md#610)。 +======= +Check out the `eslint-plugin-react-hooks` [changelog for a full list of changes](https://github.com/react/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md#610). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- @@ -314,6 +318,7 @@ CSS セレクタとして無効な特殊文字を使用していた元々の意 ## 変更履歴 {/*changelog*/} +<<<<<<< HEAD その他の注目すべき変更 - `react-dom`: 巻き上げ可能な style で nonce を使用できるように [#32461](https://github.com/facebook/react/pull/32461) - `react-dom`: React が所有するノードをコンテナとして使用し、テキストコンテンツも含まれている場合に警告を表示 [#32774](https://github.com/facebook/react/pull/32774) @@ -332,6 +337,26 @@ CSS セレクタとして無効な特殊文字を使用していた元々の意 - `react-dom`: レンダー中に中断した後にサスペンドするときのハングを回避 [#34192](https://github.com/facebook/react/pull/34192) 変更の完全なリストについては、[Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) を参照してください。 +======= +Other notable changes +- `react-dom`: Allow nonce to be used on hoistable styles [#32461](https://github.com/react/react/pull/32461) +- `react-dom`: Warn for using a React owned node as a Container if it also has text content [#32774](https://github.com/react/react/pull/32774) + +Notable bug fixes +- `react`: Stringify context as "SomeContext" instead of "SomeContext.Provider" [#33507](https://github.com/react/react/pull/33507) +- `react`: Fix infinite useDeferredValue loop in popstate event [#32821](https://github.com/react/react/pull/32821) +- `react`: Fix a bug when an initial value was passed to useDeferredValue [#34376](https://github.com/react/react/pull/34376) +- `react`: Fix a crash when submitting forms with Client Actions [#33055](https://github.com/react/react/pull/33055) +- `react`: Hide/unhide the content of dehydrated suspense boundaries if they resuspend [#32900](https://github.com/react/react/pull/32900) +- `react`: Avoid stack overflow on wide trees during Hot Reload [#34145](https://github.com/react/react/pull/34145) +- `react`: Improve component stacks in various places [#33629](https://github.com/react/react/pull/33629), [#33724](https://github.com/react/react/pull/33724), [#32735](https://github.com/react/react/pull/32735), [#33723](https://github.com/react/react/pull/33723) +- `react`: Fix a bug with React.use inside React.lazy-ed Component [#33941](https://github.com/react/react/pull/33941) +- `react-dom`: Stop warning when ARIA 1.3 attributes are used [#34264](https://github.com/react/react/pull/34264) +- `react-dom`: Fix a bug with deeply nested Suspense inside Suspense fallbacks [#33467](https://github.com/react/react/pull/33467) +- `react-dom`: Avoid hanging when suspending after aborting while rendering [#34192](https://github.com/react/react/pull/34192) + +For a full list of changes, please see the [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- diff --git a/src/content/blog/2025/10/07/react-compiler-1.md b/src/content/blog/2025/10/07/react-compiler-1.md index db079a20b..227fae31d 100644 --- a/src/content/blog/2025/10/07/react-compiler-1.md +++ b/src/content/blog/2025/10/07/react-compiler-1.md @@ -132,7 +132,11 @@ export default defineConfig([ } ``` +<<<<<<< HEAD React Compiler ルールを有効にするには、`recommended` プリセットを使用することをお勧めします。詳しい手順については [README](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md) も確認してください。以下は、React Conf で紹介したいくつかの例です。 +======= +To enable React Compiler rules, we recommend using the `recommended` preset. You can also check out the [README](https://github.com/react/react/blob/main/packages/eslint-plugin-react-hooks/README.md) for more instructions. Here are a few examples we featured at React Conf: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca - [`set-state-in-render`](/reference/eslint-plugin-react-hooks/lints/set-state-in-render) でレンダーループを引き起こす `setState` パターンをキャッチする。 - [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect) でエフェクト内の高コストな処理にフラグを立てる。 diff --git a/src/content/blog/2025/12/03/critical-security-vulnerability-in-react-server-components.md b/src/content/blog/2025/12/03/critical-security-vulnerability-in-react-server-components.md index 022c05952..4b01adbbf 100644 --- a/src/content/blog/2025/12/03/critical-security-vulnerability-in-react-server-components.md +++ b/src/content/blog/2025/12/03/critical-security-vulnerability-in-react-server-components.md @@ -34,7 +34,11 @@ React Server Components に、認証不要のリモートコード実行の脆 ## 直ちに対応を {/*immediate-action-required*/} +<<<<<<< HEAD バージョン [19.0.1](https://github.com/facebook/react/releases/tag/v19.0.1)、[19.1.2](https://github.com/facebook/react/releases/tag/v19.1.2)、および [19.2.1](https://github.com/facebook/react/releases/tag/v19.2.1) で修正が導入されました。上記のパッケージを使用している場合は、直ちに修正済みバージョンのいずれかにアップグレードしてください。 +======= +A fix was introduced in versions [19.0.1](https://github.com/react/react/releases/tag/v19.0.1), [19.1.2](https://github.com/react/react/releases/tag/v19.1.2), and [19.2.1](https://github.com/react/react/releases/tag/v19.2.1). If you are using any of the above packages please upgrade to any of the fixed versions immediately. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca アプリの React コードがサーバを使用していない場合、この脆弱性の影響は受けません。アプリが React Server Components をサポートするフレームワーク、バンドラ、またはバンドラプラグインを使用していない場合、この脆弱性の影響は受けません。 @@ -193,7 +197,11 @@ npm install react@latest react-dom@latest react-server-dom-webpack@latest これはセキュリティ上の問題を緩和するために必要ですが、`react` および `react-dom` を更新する必要はなく、そのため React Native でのバージョン不一致エラーが発生することはありません。 +<<<<<<< HEAD 詳細については[この issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) を参照してください。 +======= +See [this issue](https://github.com/react/react-native/issues/54772#issuecomment-3617929832) for more information. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ## タイムライン {/*timeline*/} diff --git a/src/content/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components.md b/src/content/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components.md index e0cbd4139..e959c7635 100644 --- a/src/content/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components.md +++ b/src/content/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components.md @@ -98,7 +98,11 @@ _Updated January 26, 2026._ これはセキュリティ上の問題を緩和するために必要ですが、`react` および `react-dom` を更新する必要はなく、そのため React Native でのバージョン不一致エラーが発生することはありません。 +<<<<<<< HEAD 詳細については[この issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) を参照してください。 +======= +See [this issue](https://github.com/react/react-native/issues/54772#issuecomment-3617929832) for more information. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- diff --git a/src/content/blog/index.md b/src/content/blog/index.md index bf353576e..90affa70e 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -154,7 +154,11 @@ React チームより幾つかのお知らせがあります! ### すべてのリリースノート {/*all-release-notes*/} +<<<<<<< HEAD React のすべてのリリースが個別のブログ記事になるわけではありませんが、React リポジトリの [`CHANGELOG.md`](https://github.com/facebook/react/blob/main/CHANGELOG.md) ファイルや [Releases](https://github.com/facebook/react/releases) ページで、すべてのリリースの詳細な変更履歴を見ることができます。 +======= +Not every React release deserves its own blog post, but you can find a detailed changelog for every release in the [`CHANGELOG.md`](https://github.com/react/react/blob/main/CHANGELOG.md) file in the React repository, as well as on the [Releases](https://github.com/react/react/releases) page. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- diff --git a/src/content/community/acknowledgements.md b/src/content/community/acknowledgements.md index a58f44283..1ccff4a6d 100644 --- a/src/content/community/acknowledgements.md +++ b/src/content/community/acknowledgements.md @@ -4,7 +4,11 @@ title: 謝辞 <Intro> +<<<<<<< HEAD オリジナルの React は [Jordan Walke](https://github.com/jordwalke) によって作成されました。現在、React に取り組んでいる[フルタイムの専門チーム](/community/team)があり、また [1000 名を超えるオープンソース貢献者](https://github.com/facebook/react/graphs/contributors)がいます。 +======= +React was originally created by [Jordan Walke.](https://github.com/jordwalke) Today, React has a [dedicated full-time team working on it](/community/team), as well as over a thousand [open source contributors.](https://github.com/react/react/graphs/contributors) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Intro> diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index 7adbb4035..3dd5eba45 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -25,6 +25,11 @@ September 10-11, 2026. In-person in Zurich, Switzerland [Website](https://conf.zurichjs.com?utm_campaign=ZurichJS_Conf&utm_source=referral&utm_content=reactjs_community_conferences) - [Twitter](https://x.com/zurichjs) - [LinkedIn](https://www.linkedin.com/company/zurichjs/) +### React Conf Japan 2027 {/*react-conf-japan-2027*/} +April 24, 2027. In-person in Tokyo, Japan + +[Website](https://reactconf.jp/) - [Twitter](https://x.com/reactconfjp) + ## Past Conferences {/*past-conferences*/} ### CityJS New Delhi 2026 {/*cityjs-newdelhi-2026*/} diff --git a/src/content/community/index.md b/src/content/community/index.md index cec280fd2..239ca0ca6 100644 --- a/src/content/community/index.md +++ b/src/content/community/index.md @@ -10,7 +10,11 @@ React には何百万人もの開発者のコミュニティが存在します ## 行動規範 {/*code-of-conduct*/} +<<<<<<< HEAD React のコミュニティに参加する前に、[私たちの行動規範 (Code of Conduct) をお読みください](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md)。私たちは [Contributor Covenant](https://www.contributor-covenant.org/) を採用しており、すべてのコミュニティメンバが記載されているガイドラインを遵守することを期待しています。 +======= +Before participating in React's communities, [please read our Code of Conduct.](https://github.com/react/react/blob/main/CODE_OF_CONDUCT.md) We have adopted the [Contributor Covenant](https://www.contributor-covenant.org/) and we expect that all community members adhere to the guidelines within. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ## Stack Overflow {/*stack-overflow*/} diff --git a/src/content/community/team.md b/src/content/community/team.md index af0f7f8f9..9bed69f0a 100644 --- a/src/content/community/team.md +++ b/src/content/community/team.md @@ -4,6 +4,7 @@ title: "チーム紹介" <Intro> +<<<<<<< HEAD React の開発を主導しているのは Meta でフルタイムで働く専門チームです。また、世界中の人々からの貢献も受けています。 </Intro> @@ -32,12 +33,128 @@ React コアチームのメンバーは、コアコンポーネントの API、R <TeamMember name="Jack Pope" permalink="jack-pope" photo="/images/team/jack-pope.jpg" github="jackpope" personal="jackpope.me" title="Engineer at Meta"> Jack は AutoHotkey を人に紹介されてから、思いつく限りの作業を自動化するスクリプトを書いてきました。そこで限界を感じてウェブアプリの開発に頭から飛び込んだ後は、それ一筋です。最近では Instagram のウェブプラットフォームに携わったのち、React チームにやってきました。好きなプログラミング言語は JSX です。 +======= +React development is led by contributors from companies and communities all over the world. + +</Intro> + +React work is organized into working groups, each responsible for an area of the project such as Server, DOM, Fiber, Docs & Community, Compiler, DevX, and React Native. Each working group is represented on the React Leadership Council, which coordinates direction across the project. + +## Leadership Council {/*leadership-council*/} + +<TeamMember name="Andrew Clark" permalink="andrew-clark" photo="/images/team/acdlite.jpg" github="acdlite" twitter="acdlite" threads="acdlite" title="Engineer at Vercel" group="Fiber*, DOM"> + Andrew got started with web development by making sites with WordPress, and eventually tricked himself into doing JavaScript. His favorite pastime is karaoke. Andrew is either a Disney villain or a Disney princess, depending on the day. +</TeamMember> + +<TeamMember name="Jack Pope" permalink="jack-pope" photo="/images/team/jack-pope.jpg" github="jackpope" personal="jackpope.me" title="Engineer at Meta" group="DOM*, Fiber"> + Shortly after being introduced to AutoHotkey, Jack had written scripts to automate everything he could think of. When reaching limitations there, he dove headfirst into web app development and hasn't looked back. Most recently, Jack worked on the web platform at Instagram before moving to React. His favorite programming language is JSX. +</TeamMember> + +<TeamMember name="Mofei Zhang" permalink="mofei-zhang" photo="/images/team/mofei-zhang.png" github="mofeiZ" threads="z_mofei" title="Engineer at Meta" group="Compiler*"> + Mofei started programming when she realized it can help her cheat in video games. She focused on operating systems in undergrad / grad school, but now finds herself happily tinkering on React. Outside of work, she enjoys debugging bouldering problems and planning her next backpacking trip(s). +</TeamMember> + +<TeamMember name="Moti Zilberman" permalink="moti-zilberman" photo="/images/team/gh-motiz88.jpg" github="motiz88" title="Engineer at Meta" group="DevX*" /> + +<TeamMember name="Nicola Corti" permalink="nicola-corti" photo="/images/team/gh-cortinico.jpg" github="cortinico" title="Engineer at Meta" group="React Native*, Docs & Community" /> + +<TeamMember name="Rick Hanlon" permalink="rick-hanlon" photo="/images/team/rickhanlonii.jpg" github="rickhanlonii" twitter="rickyfm" threads="rickhanlonii" bsky="ricky.fm" title="Engineer at Meta" group="Docs & Community*, DOM, Fiber, Server, DevX"> + Ricky majored in theoretical math and somehow found himself on the React Native team for a couple years before joining the React team. When he's not programming you can find him snowboarding, biking, climbing, golfing, or closing GitHub issues that do not match the issue template. +</TeamMember> + +<TeamMember name="Sebastian Silbermann" permalink="sebastian-silbermann" photo="/images/team/sebsilbermann.jpg" github="eps1lon" twitter="sebsilbermann" threads="sebsilbermann" title="Engineer at Vercel" group="Server*, DOM, Fiber, DevX"> + Sebastian learned programming to make the browser games he played during class more enjoyable. Eventually this lead to contributing to as much open source code as possible. Outside of coding he's busy making sure people don't confuse him with the other Sebastians and Zilberman of the React community. +</TeamMember> + +## Working Group members {/*working-group-members*/} + +<TeamMember name="Alex Hunt" permalink="alex-hunt" photo="/images/team/gh-huntie.jpg" github="huntie" title="Engineer at Meta" group="DevX, React Native" /> + +<TeamMember name="Aurora Scharff" permalink="aurora-scharff" photo="/images/team/gh-aurorascharff.jpg" github="aurorascharff" title="Engineer at Vercel" group="Docs & Community" /> + +<TeamMember name="Brent Vatne" permalink="brent-vatne" photo="/images/team/gh-brentvatne.jpg" github="brentvatne" title="Engineer at Expo" group="React Native" /> + +<TeamMember name="Dan Abramov" permalink="dan-abramov" photo="/images/team/gaearon.jpg" github="gaearon" bsky="danabra.mov" title="Engineer at Vercel" group="Docs & Community"> + Dan got into programming after he accidentally discovered Visual Basic inside Microsoft PowerPoint. He has found his true calling in turning [Sebastian](#sebastian-markbåge)'s tweets into long-form blog posts. Dan occasionally wins at Fortnite by hiding in a bush until the game ends. +</TeamMember> + +<TeamMember name="Hendrik Liebau" permalink="hendrik-liebau" photo="/images/team/hendrik.jpg" github="unstubbable" bsky="unstubbable.bsky.social" twitter="unstubbable" title="Engineer at Vercel" group="Server"> + Hendrik’s journey in tech started in the late 90s when he built his first websites with Netscape Communicator. After earning a diploma in computer science and working at digital agencies, he built a React Server Components bundler and library, paving the way to his role on the Next.js team. Outside of work, he enjoys cycling and tinkering in his workshop. +</TeamMember> + +<TeamMember name="Jordan Eldredge" permalink="jordan-eldredge" photo="/images/team/gh-captbaritone.jpg" github="captbaritone" title="Engineer at Meta" group="Server" /> + +<TeamMember name="Josh Story" permalink="josh-story" photo="/images/team/josh.jpg" github="gnoff" bsky="storyhb.com" title="Engineer at Vercel" group="DOM, Fiber, Server"> + Josh majored in Mathematics and discovered programming while in college. His first professional developer job was to program insurance rate calculations in Microsoft Excel, the paragon of Reactive Programming which must be why he now works on React. In between that time Josh has been an IC, Manager, and Executive at a few startups. outside of work he likes to push his limits with cooking. +</TeamMember> + +<TeamMember name="Kevin Gozali" permalink="kevin-gozali" photo="/images/team/gh-fkgozali.jpg" github="fkgozali" title="Engineer at Meta" group="React Native" /> + +<TeamMember name="Khalef Hosany" permalink="khalef-hosany" photo="/images/team/gh-khalef1.jpg" github="Khalef1" title="Engineer at Microsoft" group="React Native" /> + +<TeamMember name="Krzysztof Magiera" permalink="krzysztof-magiera" photo="/images/team/gh-kmagiera.jpg" github="kmagiera" title="Engineer at Software Mansion" group="React Native" /> + +<TeamMember name="Lauren Tan" permalink="lauren-tan" photo="/images/team/lauren.jpg" github="poteto" twitter="potetotes" threads="potetotes" bsky="no.lol" title="Engineer at Cursor" group="Compiler"> + Lauren's programming career peaked when she first discovered the `<marquee>` tag. She’s been chasing that high ever since. She studied Finance instead of CS in college, so she learned to code using Excel. Lauren enjoys dropping cheeky memes in chat, playing video games with her partner, learning Korean, and petting her dog Zelda. +</TeamMember> + +<TeamMember name="Matt Carroll" permalink="matt-carroll" photo="/images/team/matt-carroll.png" github="mattcarrollcode" twitter="mattcarrollcode" threads="mattcarrollcode" title="Developer Advocate at Meta" group="Docs & Community"> + Matt stumbled into coding, and since then, has become enamored with creating things in communities that can’t be created alone. Prior to React, he worked on YouTube, the Google Assistant, Fuchsia, and Google Cloud AI and Evernote. When he's not trying to make better developer tools he enjoys the mountains, jazz, and spending time with his family. +</TeamMember> + +<TeamMember name="Michael Leon" permalink="michael-leon" photo="/images/team/gh-fbmal7.jpg" github="fbmal7" title="Engineer at Meta" group="DevX" /> + +<TeamMember name="Michał Pierzchała" permalink="michal-pierzchala" photo="/images/team/gh-thymikee.jpg" github="thymikee" title="Engineer at Callstack" group="React Native" /> + +<TeamMember name="Mike Vitousek" permalink="mike-vitousek" photo="/images/team/mike.jpg" github="mvitousek" title="Engineer at Meta" group="Compiler"> + Mike went to grad school dreaming of becoming a professor but realized that he liked building things a lot more than writing grant applications. Mike joined Meta to work on Javascript infrastructure, which ultimately led him to work on the React Compiler. When not hacking on either Javascript or OCaml, Mike can often be found hiking or skiing in the Pacific Northwest. +</TeamMember> + +<TeamMember name="Pieter De Baets" permalink="pieter-de-baets" photo="/images/team/gh-javache.jpg" github="javache" title="Engineer at Meta" group="Compiler, Fiber, React Native" /> + +<TeamMember name="Riccardo Cipolleschi" permalink="riccardo-cipolleschi" photo="/images/team/gh-cipolleschi.png" github="cipolleschi" title="Engineer at Meta" group="Docs & Community, React Native" /> + +<TeamMember name="Rob Hogan" permalink="rob-hogan" photo="/images/team/gh-rh389.jpg" github="rh389" title="Engineer at Meta" group="DevX" /> + +<TeamMember name="Rubén Norte" permalink="ruben-norte" photo="/images/team/gh-rubennorte.jpg" github="rubennorte" title="Engineer at Meta" group="Fiber" /> + +<TeamMember name="Ruslan Lesiutin" permalink="ruslan-lesiutin" photo="/images/team/lesiutin.jpg" github="hoxyq" twitter="ruslanlesiutin" threads="lesiutin" title="Engineer at Meta" group="DOM, DevX"> + Ruslan's introduction to UI programming started when he was a kid by manually editing HTML templates for his custom gaming forums. Somehow, he ended up majoring in Computer Science. He enjoys music, games, and memes. Mostly memes. +</TeamMember> + +<TeamMember name="Sam Selikoff" permalink="sam-selikoff" photo="/images/team/gh-samselikoff.jpg" github="samselikoff" title="Engineer at Vercel" group="Docs & Community" /> + +<TeamMember name="Sophie Alpert" permalink="sophie-alpert" photo="/images/team/sophiebits.jpg" github="sophiebits" twitter="sophiebits" threads="sophiebits" personal="sophiebits.com" title="Independent Engineer" group="Docs & Community, DOM, Fiber"> + Four days after React was released, Sophie rewrote the entirety of her then-current project to use it, which she now realizes was perhaps a bit reckless. After she became the project's #1 committer, she wondered why she wasn't getting paid by Facebook like everyone else was and joined the team officially to lead React through its adolescent years. Though she quit that job years ago, somehow she's still in the team's group chats and “providing value”. +</TeamMember> + +<TeamMember name="Steven Moyes" permalink="steven-moyes" photo="/images/team/gh-stmoy.jpg" github="stmoy" title="Engineer at Amazon" group="React Native" /> + +<TeamMember name="Vitali Zaidman" permalink="vitali-zaidman" photo="/images/team/gh-vzaidman.jpg" github="vzaidman" title="Engineer at Meta" group="DevX" /> + +<TeamMember name="Vojtěch Šimek" permalink="vojtech-simek" photo="/images/team/gh-simek.png" github="simek" title="Developer" group="Docs & Community" /> + +## Advisors {/*advisors*/} + +<TeamMember name="Eli White" permalink="eli-white" photo="/images/team/eli-white.jpg" github="elicwhite" twitter="Eli_White" threads="elicwhite" title="Engineer at Meta"> + Eli got into programming after he got suspended from middle school for hacking. He has been working on React and React Native since 2017. He enjoys eating treats, especially ice cream and apple pie. You can find Eli trying quirky activities like parkour, indoor skydiving, and aerial silks. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </TeamMember> <TeamMember name="Jason Bonta" permalink="jason-bonta" photo="/images/team/jasonbonta.jpg" threads="someextent" title="Engineering Manager at Meta"> Jason は、組み込み C 開発を完全に捨ててフロントエンドエンジニアとしてのキャリアを選びました。難解な CSS の知識と美しい UI への情熱を武器に 2010 年に Facebook に参加し、JavaScript 開発の成長を見届けることができたことを光栄に思っています。`for...of` ループの動作は理解していないかもしれませんが、素晴らしい人々と一緒に、素晴らしい UX を実現するプロジェクトに取り組むことを愛しています。 </TeamMember> +<TeamMember name="Jimmy Lai" permalink="jimmy-lai" photo="/images/team/jimmy-lai.jpg" github="feedthejim" title="Engineering Director, Next.js at Vercel"> + Like many others, Jimmy started programming with the hopes of being able to work in the gaming industry. Fast forward a few years, he somehow decided that React and Javascript were pretty fun and that helping other developers build fast experiences was a more interesting life goal. After starting his career at Meta, working on product infrastructure and (briefly) on React Native, Jimmy now works at Vercel, where he helps his team build Next.js. He sadly does not get much time for video games anymore. +</TeamMember> + +<TeamMember name="Seth Webster" permalink="seth-webster" photo="/images/team/seth.jpg" github="sethwebster" twitter="sethwebster" threads="sethwebster" personal="sethwebster.com" title="Executive Director, React Foundation, Chief Developer Evangelist at Expo"> + Seth started programming as a kid growing up in Tucson, AZ. After school, he was bitten by the music bug and was a touring musician for about 10 years before returning to *work*, starting with Intuit. In his spare time, he loves [taking pictures](https://www.sethwebster.com) and flying for animal rescues in the northeastern United States. +</TeamMember> + +## Emeritus {/*emeritus*/} + <TeamMember name="Joe Savona" permalink="joe-savona" photo="/images/team/joe.jpg" github="josephsavona" twitter="en_JS" threads="joesavona" title="Engineer at Meta"> Joe は数学と哲学を専攻する予定でしたが、Matlab で物理シミュレーションを書いたことからコンピュータサイエンスに興味を持ちました。React に取り組む前は、Relay、RSocket.js、Skip プログラミング言語などに取り組んでいました。何かしらのリアクティブシステムを構築する傍らでは、ランニングをしたり、日本語を勉強したり、家族と過ごしたりしています。 </TeamMember> @@ -46,6 +163,7 @@ React コアチームのメンバーは、コアコンポーネントの API、R Jordan のコーディングは、iPhone アプリの開発から始まり、for ループの意味を理解する前にビューコントローラーのスタック管理を行っていました。開発者に愛される技術に取り組むことが好きで、それが彼を自然と React に引き寄せました。仕事以外では、読書、カイトボード、ギター演奏を楽しんでいます。 </TeamMember> +<<<<<<< HEAD <TeamMember name="Josh Story" permalink="josh-story" photo="/images/team/josh.jpg" github="gnoff" bsky="storyhb.com" title="Engineer at Vercel"> Josh は大学で数学を専攻し、そこでプログラミングに出会いました。プロ開発者としての最初の仕事は、リアクティブプログラミングのお手本たる Microsoft Excel で保険料計算プログラムを書くことであり、きっとそれが今 React に取り組んでいる理由なのでしょう。その間 Josh はいくつかのスタートアップで IC、マネージャー、エグゼクティブも務めてきました。仕事以外では、料理で自分の限界に挑戦することが好きです。 </TeamMember> @@ -66,10 +184,13 @@ React コアチームのメンバーは、コアコンポーネントの API、R Mofei はゲームでチートを行うのに役立つと気づいたことでプログラミングを始めました。彼女は学部・大学院ではオペレーティングシステムを専門にしていましたが、今では React いじりを楽しんでいます。仕事の外では、ボルダリングの問題をデバッグすることや、次回のバックパック旅行の計画を楽しんでいます。 </TeamMember> +======= +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca <TeamMember name="Pieter Vanderwerff" permalink="pieter-vanderwerff" photo="/images/team/pieter.jpg" github="pieterv" threads="pietervanderwerff" title="Engineer at Meta"> Pieter は建築学を学びましたが、就職できなかったため自分用のウェブサイトを作ったところ、そこから事態が発展していきました。Meta では、パフォーマンスや言語、そして現在は React の開発に取り組んでいます。プログラミングをしていない時は、道路から外れた山の中にいます。 </TeamMember> +<<<<<<< HEAD <TeamMember name="Rick Hanlon" permalink="rick-hanlon" photo="/images/team/rickhanlonii.jpg" github="rickhanlonii" twitter="rickhanlonii" threads="rickhanlonii" bsky="ricky.fm" title="Engineer at Meta"> Ricky は理論数学を専攻していましたが、どういうわけか React Native チームで数年過ごしたあと、React チームにやってきました。プログラミングをしていないときは、スノーボード、自転車、クライミング、ゴルフを楽しんだり、テンプレートに合致しない GitHub の issue をクローズしたりしています。 </TeamMember> @@ -78,10 +199,13 @@ React コアチームのメンバーは、コアコンポーネントの API、R Ruslan の UI プログラミングの経験は、子供のころにゲーム掲示板で HTML テンプレートを手でカスタマイズしたのが最初でした。その後いろいろあってコンピュータサイエンスを専攻することとなりました。好きなものは音楽、ゲーム、ネットミームです。特にネットミームです。 </TeamMember> +======= +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca <TeamMember name="Sebastian Markbåge" permalink="sebastian-markbåge" photo="/images/team/sebmarkbage.jpg" github="sebmarkbage" twitter="sebmarkbage" threads="sebmarkbage" title="Engineer at Vercel"> Sebastian の専攻は心理学でした。普段の彼はもの静かです。彼が何かを言ったとしても、数か月後まで他の人には理解できないことがよくあります。彼の姓の発音は本来 "mark-boa-geh" ですが、実用性を優先して "mark-beige" に落ち着きました。彼の React へのアプローチも実用主義的です。 </TeamMember> +<<<<<<< HEAD <TeamMember name="Sebastian Silbermann" permalink="sebastian-silbermann" photo="/images/team/sebsilbermann.jpg" github="eps1lon" twitter="sebsilbermann" threads="sebsilbermann" title="Engineer at Vercel"> Sebastian は、授業中に遊んでいたブラウザゲームをより楽しくするためにプログラミングを学びました。それはいずれ、オープンソースコードに可能な限りの貢献をすることにつながりました。コーディング以外の時間では、彼は React コミュニティにいるほかの Sebastian や Zilberman と混同されないように頑張っています。 </TeamMember> @@ -94,10 +218,16 @@ React コアチームのメンバーは、コアコンポーネントの API、R Sophie は React がリリースされてから 4 日後、当時のプロジェクトを全部 React を使って書き直しました(今思えば少々無謀だったかもしれません)。彼女がプロジェクトのナンバーワンコミッタになった後、ほかの全員が Facebook から給料をもらっているのに自分だけがもらっていないのはなぜかと思い、成長期の React を主導するために正式にチームに参加しました。その仕事は数年前に辞めているのですが、なぜかまだチームのグループチャットで「価値を提供」しています。 </TeamMember> +======= +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca <TeamMember name="Yuzhi Zheng" permalink="yuzhi-zheng" photo="/images/team/yuzhi.jpg" github="yuzhi" twitter="yuzhiz" threads="yuzhiz" title="Engineering Manager at Meta"> Yuzhi は学校でコンピュータサイエンスを学びました。彼女は、実際に研究室に行かなくてもコードが生き生きと動く瞬間の喜びが好きでした。現在の彼女は React org のマネージャです。その前は、Relay のデータフェッチングフレームワークに取り組んでいました。余暇には、ガーデニングや家のリフォームを通じた生活の最適化にいそしんでいます。 </TeamMember> +<<<<<<< HEAD ## 過去の貢献者 {/*past-contributors*/} 過去のチームメンバーや、過去長年にわたり React に大きく貢献した人々については、[謝辞](/community/acknowledgements)ページに掲載されています。 +======= +You can find the past team members and other people who significantly contributed to React over the years on the [acknowledgements](/community/acknowledgements) page. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca diff --git a/src/content/community/versioning-policy.md b/src/content/community/versioning-policy.md index e4d5010a0..d808f2ce1 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -134,9 +134,15 @@ React へのすべての更新は、一般に公開される前に広範な内 ```console yarn upgrade react@canary react-dom@canary ``` +<<<<<<< HEAD - 更新されたパッケージに対してテストスイートを実行します。 - すべてのテストが通過した場合はおめでとうございます! あなたのプロジェクトは次のマイナー React リリースでも動作すると期待できます。 - 何か予期せぬ問題が発生した場合、[問題を報告](https://github.com/facebook/react/issues)してください。 +======= +- Run your test suite against the updated packages. +- If everything passes, great! You can expect that your project will work with the next minor React release. +- If something breaks unexpectedly, please let us know by [filing an issue](https://github.com/react/react/issues). +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca このワークフローを採用しているプロジェクトのひとつが Next.js です。例として彼らの [CircleCI 設定](https://github.com/zeit/next.js/blob/c0a1c0f93966fe33edd93fb53e5fafb0dcd80a9e/.circleci/config.yml)を参照してください。 @@ -166,4 +172,8 @@ Experimental に対して統合テストを実行することに価値がある 新しい実験を発表する準備が整ったときには [React ブログ](/blog) に投稿しますが、すべての実験を公表するわけではありません。 +<<<<<<< HEAD 変更の包括的なリストは、公開 GitHub リポジトリの[履歴](https://github.com/facebook/react/commits/main)でいつでも参照できます。 +======= +You can always refer to our public GitHub repository's [history](https://github.com/react/react/commits/main) for a comprehensive list of changes. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca diff --git a/src/content/learn/react-compiler/debugging.md b/src/content/learn/react-compiler/debugging.md index 80a39914e..d189afd46 100644 --- a/src/content/learn/react-compiler/debugging.md +++ b/src/content/learn/react-compiler/debugging.md @@ -43,10 +43,17 @@ React Compiler がアプリケーションの不具合を引き起こす代表 ### ビルド時のコンパイラエラー {/*compiler-build-errors*/} +<<<<<<< HEAD コンパイラエラーでビルドが予期せず失敗した場合、これはコンパイラのバグである可能性が高いです。以下の情報を添えて [facebook/react](https://github.com/facebook/react/issues) リポジトリに報告してください。 - エラーメッセージ - エラーを引き起こしたコード - React とコンパイラのバージョン +======= +If you encounter a compiler error that unexpectedly breaks your build, this is likely a bug in the compiler. Report it to the [react/react](https://github.com/react/react/issues) repository with: +- The error message +- The code that caused the error +- Your React and compiler versions +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ### ランタイムエラー {/*runtime-issues*/} @@ -78,6 +85,7 @@ function ProblematicComponent() { コンパイラバグを発見したと思われる場合は以下のようにしてください。 +<<<<<<< HEAD 1. **React のルール違反ではないことを確認する** - ESLint でチェックする 2. **最小限の再現方法を特定する** - 小さな例で問題を切り分ける 3. **コンパイラを無効化した状態でテストする** - 問題がコンパイル時にのみ発生するかを確認する @@ -86,6 +94,16 @@ function ProblematicComponent() { - 最小限の再現コード - 期待される動作と実際の動作 - エラーメッセージ +======= +1. **Verify it's not a Rules of React violation** - Check with ESLint +2. **Create a minimal reproduction** - Isolate the issue in a small example +3. **Test without the compiler** - Confirm the issue only occurs with compilation +4. **File an [issue](https://github.com/react/react/issues/new?template=compiler_bug_report.yml)**: + - React and compiler versions + - Minimal reproduction code + - Expected vs actual behavior + - Any error messages +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ## 次のステップ {/*next-steps*/} diff --git a/src/content/learn/react-compiler/installation.md b/src/content/learn/react-compiler/installation.md index c99240fae..ceb89a82f 100644 --- a/src/content/learn/react-compiler/installation.md +++ b/src/content/learn/react-compiler/installation.md @@ -64,9 +64,36 @@ module.exports = { ### Vite {/*vite*/} +<<<<<<< HEAD Vite を使用している場合は、プラグインを vite-plugin-react に追加できます。 +======= +If you use Vite with version 6.0.0 or later of `@vitejs/plugin-react`, you can use the `reactCompilerPreset`: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca -```js {3,9} +<TerminalBlock> +npm install -D @rolldown/plugin-babel +</TerminalBlock> + +```js {3-4,9-11} +// vite.config.js +import { defineConfig } from 'vite'; +import react, { reactCompilerPreset } from '@vitejs/plugin-react'; +import babel from '@rolldown/plugin-babel'; + +export default defineConfig({ + plugins: [ + react(), + babel({ + presets: [reactCompilerPreset()] + }), + ], +}); +``` + +<Note> +In `@vitejs/plugin-react@6.0.0`, the inline Babel option was removed. If you're using an older version, you can use: + +```js // vite.config.js import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; @@ -81,26 +108,25 @@ export default defineConfig({ ], }); ``` +</Note> +<<<<<<< HEAD または、Vite 用の Babel プラグインを別に使用したい場合は以下のようにします。 +======= +Alternatively, you can use the Babel plugin directly with `@rolldown/plugin-babel`: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca -<TerminalBlock> -npm install -D vite-plugin-babel -</TerminalBlock> - -```js {2,11} +```js {3,9} // vite.config.js -import babel from 'vite-plugin-babel'; import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; +import babel from '@rolldown/plugin-babel'; export default defineConfig({ plugins: [ react(), babel({ - babelConfig: { - plugins: ['babel-plugin-react-compiler'], - }, + plugins: ['babel-plugin-react-compiler'], }), ], }); @@ -172,7 +198,11 @@ ESLint プラグインをインストールします。 npm install -D eslint-plugin-react-hooks@latest </TerminalBlock> +<<<<<<< HEAD `eslint-plugin-react-hooks` をまだ設定していない場合は、[readme のインストール手順](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation)に従ってください。コンパイラのルールは `recommended-latest` プリセットで利用できます。 +======= +If you haven't already configured eslint-plugin-react-hooks, follow the [installation instructions in the readme](https://github.com/react/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation). The compiler rules are available in the `recommended-latest` preset. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ESLint ルールは以下を行います。 - [React のルール](/reference/rules)の違反の特定 diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index a33c43b14..efde6c94a 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -899,6 +899,7 @@ body { ### React Developer Tools {/*react-developer-tools*/} +<<<<<<< HEAD React DevTools を使うと、React コンポーネントの props や state を確認することができます。React DevTools タブは、CodeSandbox の *Browser* セクションの下部にあります。 ![CodeSandbox 内の React DevTools](../images/tutorial/codesandbox-devtools.png) @@ -906,12 +907,26 @@ React DevTools を使うと、React コンポーネントの props や state を 画面上の特定のコンポーネントについて調べるには、React DevTools の左上にあるボタンを使用します。 ![React DevTools でページ上のコンポーネントを選択する](../images/tutorial/devtools-select.gif) +======= +React Developer Tools let you check the props and the state of your React components. It is available as a [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/), and [Edge](https://microsoftedge.microsoft.com/addons/detail/react-developer-tools/gpphkfbcpidddadnkolkpfckpihlkkil) browser extension. -<Note> +After you install it, a new *Components* tab will appear in your browser Developer Tools for sites using React. If you're following along in CodeSandbox, you'd need to first open your sandbox preview in a new tab: + +![opening in new tab](../images/tutorial/sandbox-new-tab.png) + +Then, on the preview page, open your browser's DevTools and find the *Components* tab: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca +![components tab](../images/tutorial/components-tab.png) + +<<<<<<< HEAD ローカル開発をしている場合、React DevTools は [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)、[Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/)、そして [Edge](https://microsoftedge.microsoft.com/addons/detail/react-developer-tools/gpphkfbcpidddadnkolkpfckpihlkkil) ブラウザの拡張機能として利用できます。インストールすると、React を利用しているサイトでは *Components* タブがブラウザの開発者ツールに表示されるようになります。 +======= +To inspect a particular component on the screen, use the button in the top left corner of the Components tab: + +![inspecting with devtools](../images/tutorial/devtools-inspect.gif) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca -</Note> ## ゲームを完成させる {/*completing-the-game*/} diff --git a/src/content/reference/eslint-plugin-react-hooks/lints/incompatible-library.md b/src/content/reference/eslint-plugin-react-hooks/lints/incompatible-library.md index e057e1978..6acffb227 100644 --- a/src/content/reference/eslint-plugin-react-hooks/lints/incompatible-library.md +++ b/src/content/reference/eslint-plugin-react-hooks/lints/incompatible-library.md @@ -16,7 +16,7 @@ These libraries were designed before React's memoization rules were fully docume ## Rule Details {/*rule-details*/} -Some libraries use patterns that aren't supported by React. When the linter detects usages of these APIs from a [known list](https://github.com/facebook/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/HIR/DefaultModuleTypeProvider.ts), it flags them under this rule. This means that React Compiler can automatically skip over components that use these incompatible APIs, in order to avoid breaking your app. +Some libraries use patterns that aren't supported by React. When the linter detects usages of these APIs from a [known list](https://github.com/react/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/HIR/DefaultModuleTypeProvider.ts), it flags them under this rule. This means that React Compiler can automatically skip over components that use these incompatible APIs, in order to avoid breaking your app. ```js // Example of how memoization breaks with these libraries @@ -135,4 +135,4 @@ function Component() { } ``` -Some other libraries do not yet have alternative APIs that are compatible with React's memoization model. If the linter doesn't automatically skip over your components or hooks that call these APIs, please [file an issue](https://github.com/facebook/react/issues) so we can add it to the linter. +Some other libraries do not yet have alternative APIs that are compatible with React's memoization model. If the linter doesn't automatically skip over your components or hooks that call these APIs, please [file an issue](https://github.com/react/react/issues) so we can add it to the linter. diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index ad6836a4a..a7c7a1bba 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -36,7 +36,11 @@ title: "<div> などの一般的なコンポーネント" * `suppressHydrationWarning`: ブーリアン値。[サーバレンダリング](/reference/react-dom/server)を使用する場合、通常、サーバとクライアントが異なる内容をレンダーすると警告が表示されます。一部の稀なケース(タイムスタンプなど)では、完全な一致を保証することが非常に困難または不可能です。`suppressHydrationWarning` を `true` に設定すると、React はその要素の属性と内容の不一致について警告しなくなります。これは 1 レベルの深さまでしか機能せず、避難ハッチとして使用することを目的としています。過度な使用はしないでください。[ハイドレーションエラーの抑制について読む](/reference/react-dom/client/hydrateRoot#suppressing-unavoidable-hydration-mismatch-errors) +<<<<<<< HEAD * `style`: CSS スタイルを持つオブジェクト。例えば `{ fontWeight: 'bold', margin: 20 }` のようなものです。DOM の [`style`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) プロパティと同様に、CSS プロパティ名は `camelCase` で記述する必要があります。例えば `font-weight` ではなく `fontWeight` と書きます。値として文字列や数値を渡すことができます。数値を渡す場合、例えば `width: 100` のようにすると、React は自動的に `px`("ピクセル")を値に追加します。ただし、それが[単位のないプロパティ](https://github.com/facebook/react/blob/81d4ee9ca5c405dce62f64e61506b8e155f38d8d/packages/react-dom-bindings/src/shared/CSSProperty.js#L8-L57)の場合は除きます。`style` は、スタイルの値が事前に分からない動的なスタイルに対してのみ使用することを推奨します。他の場合は、`className` を用いてプレーンな CSS クラスを適用する方が効率的です。[`className` と `style` について詳しく読む](#applying-css-styles) +======= +* `style`: An object with CSS styles, for example `{ fontWeight: 'bold', margin: 20 }`. Similarly to the DOM [`style`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) property, the CSS property names need to be written as `camelCase`, for example `fontWeight` instead of `font-weight`. You can pass strings or numbers as values. If you pass a number, like `width: 100`, React will automatically append `px` ("pixels") to the value unless it's a [unitless property.](https://github.com/react/react/blob/81d4ee9ca5c405dce62f64e61506b8e155f38d8d/packages/react-dom-bindings/src/shared/CSSProperty.js#L8-L57) We recommend using `style` only for dynamic styles where you don't know the style values ahead of time. In other cases, applying plain CSS classes with `className` is more efficient. [Read more about `className` and `style`.](#applying-css-styles) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca 以下の標準的な DOM プロパティは、すべての組み込みコンポーネントでサポートされています。 diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 1e0a85245..c93f7bf1d 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -48,9 +48,53 @@ title: "<form>" ## 使用法 {/*usage*/} +<<<<<<< HEAD ### クライアント上でフォーム送信を処理する {/*handle-form-submission-on-the-client*/} フォームの `action` プロパティに関数を渡すことで、フォームが送信されたときにその関数が実行されるようにします。この関数には [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) が引数として渡されるため、フォームが送信したデータにアクセスできます。これは URL のみを受け付ける本来の [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action) とは異なる、独自の動作です。`action` に指定された関数が成功した後、非制御のフィールド要素はすべてリセットされます。 +======= +### Handle form submission with an event handler {/*handle-form-submission-with-an-event-handler*/} + +Pass a function to the `onSubmit` event handler to run code when the form is submitted. By default, the browser sends the form data to the current URL and refreshes the page, so call [`e.preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) to override that behavior. + +This example reads the submitted values with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData), which collects every field by its `name`. This keeps the inputs [uncontrolled](/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form). If you instead [control an input with state](/reference/react-dom/components/input#controlling-an-input-with-a-state-variable), read from that state on submit rather than from `FormData`. + +<Sandpack> + +```js src/App.js +export default function Search() { + function handleSubmit(e) { + // Prevent the browser from reloading the page + e.preventDefault(); + + // Read the form data + const form = e.target; + const formData = new FormData(form); + const query = formData.get("query"); + alert(`You searched for '${query}'`); + } + + return ( + <form onSubmit={handleSubmit}> + <input name="query" /> + <button type="submit">Search</button> + </form> + ); +} +``` + +</Sandpack> + +<Note> + +Reading form data with `onSubmit` works in every version of React and gives you direct access to the [submit event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event), so you can call `e.preventDefault()` and read the data yourself. Passing the function to the `action` prop instead runs the submission in a [Transition](/reference/react/useTransition). React then tracks the pending state, sends thrown errors to the nearest error boundary, and lets the form work with [`useActionState`](/reference/react/useActionState) and [`useOptimistic`](/reference/react/useOptimistic). An `action` can also be a [Server Function](/reference/rsc/server-functions), which `onSubmit` does not support. + +</Note> + +### Handle form submission with an action prop {/*handle-form-submission-with-an-action-prop*/} + +Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs. Unlike `onSubmit`, an `action` runs in a [Transition](/reference/react/useTransition) and calling `e.preventDefault()` isn't needed. After the `action` function succeeds, all uncontrolled field elements in the form are reset. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca <Sandpack> diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md index a3553a381..c01839005 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -48,6 +48,7 @@ const { pipe } = renderToPipeableStream(<App />, { * `reactNode`: HTML へとレンダーしたい React ノード。例えば、`<App />` のような JSX 要素です。これはドキュメント全体を表すことが期待されているため、`App` コンポーネントは `<html>` タグをレンダーする必要があります。 +<<<<<<< HEAD * **省略可能** `options`: ストリーム関連のオプションが含まれたオブジェクト。 * **省略可能** `bootstrapScriptContent`: 指定された場合、この文字列がインラインの `<script>` タグ内に配置されます。 * **省略可能** `bootstrapScripts`: ページ上に出力する `<script>` タグに対応する URL 文字列の配列。これを使用して、[`hydrateRoot`](/reference/react-dom/client/hydrateRoot) を呼び出す `<script>` を含めます。クライアントで React をまったく実行したくない場合は省略します。 @@ -60,6 +61,20 @@ const { pipe } = renderToPipeableStream(<App />, { * **省略可能** `onShellReady`: [初期シェル](#specifying-what-goes-into-the-shell)がレンダーされた直後に呼び出されるコールバック。ここで[ステータスコードのセット](#setting-the-status-code)を行い、`pipe` をコールしてストリーミングを開始できます。React はシェルを送信した後に、[追加コンテンツ](#streaming-more-content-as-it-loads)と、ローディングフォールバックを追加コンテンツで置換するためのインライン `<script>` タグをストリーミングします。 * **省略可能** `onShellError`: 初期シェルのレンダー中にエラーが発生すると呼び出されるコールバック。引数としてエラーを受け取ります。ストリームからのバイト列送信はまだ起きておらず、`onShellReady` や `onAllReady` はコールされなくなるため、[フォールバック用の HTML シェルを出力](#recovering-from-errors-inside-the-shell)することができます。 * **省略可能** `progressiveChunkSize`: チャンクのバイト数。[デフォルトの推論方法についてはこちらを参照してください](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)。 +======= +* **optional** `options`: An object with streaming options. + * **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag. + * **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don't want to run React on the client at all. + * **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML. + * **optional** `nonce`: A [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) string to allow scripts for [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src). + * **optional** `onAllReady`: A callback that fires when all rendering is complete, including both the [shell](#specifying-what-goes-into-the-shell) and all additional [content.](#streaming-more-content-as-it-loads) You can use this instead of `onShellReady` [for crawlers and static generation.](#waiting-for-all-content-to-load-for-crawlers-and-static-generation) If you start streaming here, you won't get any progressive loading. The stream will contain the final HTML. + * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](#recovering-from-errors-outside-the-shell) or [not.](#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](#setting-the-status-code) before the shell is emitted. + * **optional** `onShellReady`: A callback that fires right after the [initial shell](#specifying-what-goes-into-the-shell) has been rendered. You can [set the status code](#setting-the-status-code) and call `pipe` here to start streaming. React will [stream the additional content](#streaming-more-content-as-it-loads) after the shell along with the inline `<script>` tags that replace the HTML loading fallbacks with the content. + * **optional** `onShellError`: A callback that fires if there was an error rendering the initial shell. It receives the error as an argument. No bytes were emitted from the stream yet, and neither `onShellReady` nor `onAllReady` will get called, so you can [output a fallback HTML shell.](#recovering-from-errors-inside-the-shell) + * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/react/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 返り値 {/*returns*/} @@ -284,6 +299,7 @@ function ProfilePage() { <Note> +<<<<<<< HEAD **サスペンスコンポーネントをアクティブ化できるのはサスペンス対応のデータソースだけです**。これには以下が含まれます: - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/getting-started/react-essentials) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -295,6 +311,9 @@ function ProfilePage() { 上記の `Posts` コンポーネントで実際にデータをロードする方法は、使用するフレームワークによって異なります。サスペンス対応のフレームワークを使用している場合、詳細はデータフェッチに関するドキュメンテーション内に記載されているはずです。 使い方の規約のある (opinionated) フレームワークを使用せずにサスペンスを使ったデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件はまだ不安定であり、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +Only data read from a source that [activates a Suspense boundary](/reference/react/Suspense#what-activates-a-suspense-boundary), such as a Promise read with [`use`](/reference/react/use), will suspend during rendering. Suspense does not detect data fetched inside an Effect or event handler. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/reference/react-dom/server/renderToReadableStream.md b/src/content/reference/react-dom/server/renderToReadableStream.md index 47d62925e..7d1a9096b 100644 --- a/src/content/reference/react-dom/server/renderToReadableStream.md +++ b/src/content/reference/react-dom/server/renderToReadableStream.md @@ -49,6 +49,7 @@ async function handler(request) { * `reactNode`: HTML へとレンダーしたい React ノード。例えば、`<App />` のような JSX 要素です。これはドキュメント全体を表すことが期待されているため、`App` コンポーネントは `<html>` タグをレンダーする必要があります。 +<<<<<<< HEAD * **省略可能** `options`: ストリーム関連のオプションが含まれたオブジェクト。 * **省略可能** `bootstrapScriptContent`: 指定された場合、この文字列がインラインの `<script>` タグ内に配置されます。 * **省略可能** `bootstrapScripts`: ページ上に出力する `<script>` タグに対応する URL 文字列の配列。これを使用して、[`hydrateRoot`](/reference/react-dom/client/hydrateRoot) を呼び出す `<script>` を含めます。クライアントで React をまったく実行したくない場合は省略します。 @@ -59,6 +60,18 @@ async function handler(request) { * **省略可能** `onError`: サーバエラーが発生するたびに発火するコールバック。[復帰可能なエラー](#recovering-from-errors-outside-the-shell)の場合も[そうでないエラー](#recovering-from-errors-inside-the-shell)の場合もあります。デフォルトでは `console.error` のみを呼び出します。これを上書きして[クラッシュレポートをログに記録する](#logging-crashes-on-the-server)場合でも `console.error` を呼び出すようにしてください。また、シェルが出力される前に[ステータスコードを調整する](#setting-the-status-code)ためにも使用できます。 * **省略可能** `progressiveChunkSize`: チャンクのバイト数。[デフォルトの推論方法についてはこちらを参照してください](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)。 * **省略可能** `signal`: [サーバでのレンダーを中止](#aborting-server-rendering)してクライアントで残りをレンダーするために使用できる [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)。 +======= +* **optional** `options`: An object with streaming options. + * **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag. + * **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don't want to run React on the client at all. + * **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML. + * **optional** `nonce`: A [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) string to allow scripts for [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src). + * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](#recovering-from-errors-outside-the-shell) or [not.](#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](#setting-the-status-code) before the shell is emitted. + * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/react/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) + * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort server rendering](#aborting-server-rendering) and render the rest on the client. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 返り値 {/*returns*/} @@ -283,6 +296,7 @@ function ProfilePage() { <Note> +<<<<<<< HEAD **サスペンスコンポーネントをアクティブ化できるのはサスペンス対応のデータソースだけです**。これには以下が含まれます: - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/getting-started/react-essentials) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -294,6 +308,9 @@ function ProfilePage() { 上記の `Posts` コンポーネントで実際にデータをロードする方法は、使用するフレームワークによって異なります。サスペンス対応のフレームワークを使用している場合、詳細はデータフェッチに関するドキュメンテーション内に記載されているはずです。 使い方の規約のある (opinionated) フレームワークを使用せずにサスペンスを使ったデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件はまだ不安定であり、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +Only data read from a source that [activates a Suspense boundary](/reference/react/Suspense#what-activates-a-suspense-boundary), such as a Promise read with [`use`](/reference/react/use), will suspend during rendering. Suspense does not detect data fetched inside an Effect or event handler. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/reference/react-dom/static/prerender.md b/src/content/reference/react-dom/static/prerender.md index 5bce0cbea..8ea95bf54 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -49,6 +49,7 @@ async function handler(request, response) { * `reactNode`: HTML へとレンダーしたい React ノード。例えば、`<App />` のような JSX 要素です。これはドキュメント全体を表すことが期待されているため、`App` コンポーネントは `<html>` タグをレンダーする必要があります。 +<<<<<<< HEAD * **省略可能** `options`: 静的生成関連のオプションが含まれたオブジェクト。 * **省略可能** `bootstrapScriptContent`: 指定された場合、この文字列がインラインの `<script>` タグ内に配置されます。 * **省略可能** `bootstrapScripts`: ページ上に出力する `<script>` タグに対応する URL 文字列の配列。これを使用して、[`hydrateRoot`](/reference/react-dom/client/hydrateRoot) を呼び出す `<script>` を含めます。クライアントで React をまったく実行したくない場合は省略します。 @@ -58,6 +59,17 @@ async function handler(request, response) { * **省略可能** `onError`: サーバエラーが発生するたびに発火するコールバック。[復帰可能なエラー](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-outside-the-shell)の場合も[そうでないエラー](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell)の場合もあります。デフォルトでは `console.error` のみを呼び出します。これを上書きして[クラッシュレポートをログに記録する](/reference/react-dom/server/renderToReadableStream#logging-crashes-on-the-server)場合でも `console.error` を呼び出すようにしてください。また、シェルが出力される前に[ステータスコードを調整する](/reference/react-dom/server/renderToReadableStream#setting-the-status-code)ためにも使用できます。 * **省略可能** `progressiveChunkSize`: チャンクのバイト数。[デフォルトの推論方法についてはこちらを参照してください](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)。 * **省略可能** `signal`: [プリレンダーを中止](#aborting-prerendering)してクライアントで残りをレンダーするために使用できる [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)。 +======= +* **optional** `options`: An object with static generation options. + * **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag. + * **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don't want to run React on the client at all. + * **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML. + * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-outside-the-shell) or [not.](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](/reference/react-dom/server/renderToReadableStream#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](/reference/react-dom/server/renderToReadableStream#setting-the-status-code) before the shell is emitted. + * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/react/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) + * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort prerendering](#aborting-prerendering) and render the rest on the client. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 返り値 {/*returns*/} @@ -275,6 +287,7 @@ function ProfilePage() { <Note> +<<<<<<< HEAD **サスペンスコンポーネントをアクティブ化できるのはサスペンス対応のデータソースだけです**。これには以下が含まれます: - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/getting-started/react-essentials) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -286,6 +299,9 @@ function ProfilePage() { 上記の `Posts` コンポーネントで実際にデータをロードする方法は、使用するフレームワークによって異なります。サスペンス対応のフレームワークを使用している場合、詳細はデータフェッチに関するドキュメンテーション内に記載されているはずです。 使い方の規約のある (opinionated) フレームワークを使用せずにサスペンスを使ったデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件はまだ不安定であり、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +Only data read from a source that [activates a Suspense boundary](/reference/react/Suspense#what-activates-a-suspense-boundary), such as a Promise read with [`use`](/reference/react/use), will suspend during rendering. Suspense does not detect data fetched inside an Effect or event handler. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/reference/react-dom/static/prerenderToNodeStream.md b/src/content/reference/react-dom/static/prerenderToNodeStream.md index a800616f3..078fbc86e 100644 --- a/src/content/reference/react-dom/static/prerenderToNodeStream.md +++ b/src/content/reference/react-dom/static/prerenderToNodeStream.md @@ -50,6 +50,7 @@ app.use('/', async (request, response) => { * `reactNode`: HTML へとレンダーしたい React ノード。例えば、`<App />` のような JSX 要素です。これはドキュメント全体を表すことが期待されているため、`App` コンポーネントは `<html>` タグをレンダーする必要があります。 +<<<<<<< HEAD * **省略可能** `options`: 静的生成関連のオプションが含まれたオブジェクト。 * **省略可能** `bootstrapScriptContent`: 指定された場合、この文字列がインラインの `<script>` タグ内に配置されます。 * **省略可能** `bootstrapScripts`: ページ上に出力する `<script>` タグに対応する URL 文字列の配列。これを使用して、[`hydrateRoot`](/reference/react-dom/client/hydrateRoot) を呼び出す `<script>` を含めます。クライアントで React をまったく実行したくない場合は省略します。 @@ -59,6 +60,17 @@ app.use('/', async (request, response) => { * **省略可能** `onError`: サーバエラーが発生するたびに発火するコールバック。[復帰可能なエラー](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-outside-the-shell)の場合も[そうでないエラー](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-inside-the-shell)の場合もあります。デフォルトでは `console.error` のみを呼び出します。これを上書きして[クラッシュレポートをログに記録する](/reference/react-dom/server/renderToPipeableStream#logging-crashes-on-the-server)場合でも `console.error` を呼び出すようにしてください。また、シェルが出力される前に[ステータスコードを調整する](/reference/react-dom/server/renderToPipeableStream#setting-the-status-code)ためにも使用できます。 * **省略可能** `progressiveChunkSize`: チャンクのバイト数。[デフォルトの推論方法についてはこちらを参照してください](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)。 * **省略可能** `signal`: [プリレンダーを中止](#aborting-prerendering)してクライアントで残りをレンダーするために使用できる [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)。 +======= +* **optional** `options`: An object with static generation options. + * **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag. + * **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don't want to run React on the client at all. + * **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML. + * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-outside-the-shell) or [not.](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](/reference/react-dom/server/renderToPipeableStream#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](/reference/react-dom/server/renderToPipeableStream#setting-the-status-code) before the shell is emitted. + * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/react/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) + * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort prerendering](#aborting-prerendering) and render the rest on the client. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 返り値 {/*returns*/} @@ -276,6 +288,7 @@ function ProfilePage() { <Note> +<<<<<<< HEAD **サスペンスコンポーネントをアクティブ化できるのはサスペンス対応のデータソースだけです**。これには以下が含まれます: - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/getting-started/react-essentials) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -287,6 +300,9 @@ function ProfilePage() { 上記の `Posts` コンポーネントで実際にデータをロードする方法は、使用するフレームワークによって異なります。サスペンス対応のフレームワークを使用している場合、詳細はデータフェッチに関するドキュメンテーション内に記載されているはずです。 使い方の規約のある (opinionated) フレームワークを使用せずにサスペンスを使ったデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件はまだ不安定であり、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +Only data read from a source that [activates a Suspense boundary](/reference/react/Suspense#what-activates-a-suspense-boundary), such as a Promise read with [`use`](/reference/react/use), will suspend during rendering. Suspense does not detect data fetched inside an Effect or event handler. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/reference/react/Activity.md b/src/content/reference/react/Activity.md index 9fc6401a2..926cd355a 100644 --- a/src/content/reference/react/Activity.md +++ b/src/content/reference/react/Activity.md @@ -755,6 +755,7 @@ video { width: 300px; margin-top: 10px; aspect-ratio: 16/9; } <Note> +<<<<<<< HEAD **プリレンダー中にフェッチされるのは、サスペンス対応のデータソースのみです**。これには以下のものが含まれます。 - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -766,6 +767,9 @@ Activity は、エフェクト内部でフェッチされたデータを検出** 上記の `Posts` コンポーネントでデータをロードする具体的な方法については、使用しているフレームワークに依存します。サスペンス対応のフレームワークを使用している場合、詳細はそのフレームワークのデータフェッチのドキュメントに記載されています。 使い方に規約のある (opinionated) フレームワーク以外でサスペンス対応のデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件は安定しておらず、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +Only data read from a source that [activates a Suspense boundary](/reference/react/Suspense#what-activates-a-suspense-boundary), such as a Promise read with [`use`](/reference/react/use), is fetched during pre-rendering. Activity does not detect data fetched inside an Effect. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Note> diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 9fb8a8d86..6167ad14e 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -1009,7 +1009,11 @@ state 値の派生はコードを冗長にし、コンポーネントを分か #### 注意点 {/*static-getderivedstatefromprops-caveats*/} +<<<<<<< HEAD - このメソッドは、原因に関係なく*すべての*レンダーで発火します。[`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) はこれとは異なり、親が再レンダーを引き起こしたときのみ発火し、ローカルの `setState` の結果としては発火しません。 +======= +- This method is fired on *every* render, regardless of the cause. This is different from [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops), which only fires when the parent causes a re-render and not as a result of a local `setState`. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca - このメソッドはコンポーネントのインスタンスにアクセスできません。お望みであれば、コンポーネントの props と state に対する純関数をクラス定義の外部に抽出することで、`static getDerivedStateFromProps` と他のクラスメソッドとの間でコードを再利用することができます。 diff --git a/src/content/reference/react/Fragment.md b/src/content/reference/react/Fragment.md index 6a5fa507d..f76286915 100644 --- a/src/content/reference/react/Fragment.md +++ b/src/content/reference/react/Fragment.md @@ -6,7 +6,11 @@ title: <Fragment> (<>...</>) `<Fragment>` を使うことで、ラッパ用のノードを用いずに要素をグループ化することができます。通常は `<>...</>` という構文で使用されます。 +<<<<<<< HEAD <Canary> フラグメントは ref を受け取ることもでき、これによりラッパ要素を追加することなく、内部の DOM ノードとやり取りすることができます。以下のリファレンスと使用法を参照してください。</Canary> +======= +<Canary>Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements.</Canary> +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ```js <> @@ -29,6 +33,7 @@ title: <Fragment> (<>...</>) #### props {/*props*/} +<<<<<<< HEAD - **省略可能** `key`: 明示的な `<Fragment>` 構文で宣言されたフラグメントは [key](/learn/rendering-lists#keeping-list-items-in-order-with-key) を持つことができます。 - <CanaryBadge /> **省略可能** `ref`: ref オブジェクト(例えば [`useRef`](/reference/react/useRef) からのもの)または[コールバック関数](/reference/react-dom/components/common#ref-callback)。React は、フラグメントでラップされた DOM ノードとやり取りするためのメソッドを実装した `FragmentInstance` を ref の値として提供します。 @@ -57,14 +62,269 @@ title: <Fragment> (<>...</>) **オブザーバメソッド:** - `observeUsing(observer)`: IntersectionObserver または ResizeObserver を使用して、フラグメントの DOM の子の監視を開始します。 - `unobserveUsing(observer)`: 指定されたオブザーバによるフラグメントの DOM の子の監視を停止します。 +======= +- **optional** `key`: Fragments declared with the explicit `<Fragment>` syntax may have [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key) +- <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. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 注意点 {/*caveats*/} +<<<<<<< HEAD - `key` をフラグメントに渡したい場合は、`<>...</>` 構文を使用することはできません。`'react'` から `Fragment` を明示的にインポートし、`<Fragment key={yourKey}>...</Fragment>` とレンダーしなければなりません。 - React は、`<><Child /></>` と `[<Child />]` のレンダー間、あるいは `<><Child /></>` と `<Child />` のレンダー間で行き来する場合に [state をリセット](/learn/preserving-and-resetting-state)しません。これは単一レベルの深さのときのみの動作です。例えば、`<><><Child /></></>` から `<Child />` への変更では state がリセットされます。具体的な振る舞いの詳細は[こちら](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b)を参照してください。 - <CanaryBadge /> `ref` をフラグメントに渡したい場合は、`<>...</>` 構文を使用することはできません。`'react'` から `Fragment` を明示的にインポートし、`<Fragment ref={yourRef}>...</Fragment>` のようにレンダーしなければなりません。 +======= +* If you want to pass `key` to a Fragment, you can't use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment key={yourKey}>...</Fragment>`. + +* 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) + +* <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>`. + +--- + +### <CanaryBadge /> `FragmentInstance` {/*fragmentinstance*/} + +When you pass a `ref` to a Fragment, React provides a `FragmentInstance` object. It implements methods for interacting with the first-level DOM children wrapped by the Fragment. + +* [`addEventListener`](#addeventlistener) and [`removeEventListener`](#removeeventlistener) manage event listeners across all first-level DOM children. +* [`dispatchEvent`](#dispatchevent) dispatches an event on the Fragment, which can bubble to the DOM parent. +* [`focus`](#focus), [`focusLast`](#focuslast), and [`blur`](#blur) manage focus across all nested children depth-first. +* [`observeUsing`](#observeusing) and [`unobserveUsing`](#unobserveusing) attach and detach `IntersectionObserver` or `ResizeObserver` instances. +* [`getClientRects`](#getclientrects) returns bounding rectangles of all first-level DOM children. +* [`getRootNode`](#getrootnode) returns the root node of the Fragment's parent. +* [`compareDocumentPosition`](#comparedocumentposition) compares the Fragment's position with another node. +* [`scrollIntoView`](#scrollintoview) scrolls the Fragment's children into view. + +--- + +#### `addEventListener(type, listener, options?)` {/*addeventlistener*/} + +Adds an event listener to all first-level DOM children of the Fragment. + +```js +fragmentRef.current.addEventListener('click', handleClick); +``` + +##### Parameters {/*addeventlistener-parameters*/} + +* `type`: A string representing the event type to listen for (e.g. `'click'`, `'focus'`). +* `listener`: The event handler function. +* **optional** `options`: An options object or boolean for capture, matching the [DOM `addEventListener` API.](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + +##### Returns {/*addeventlistener-returns*/} + +`addEventListener` does not return anything (`undefined`). + +--- + +#### `removeEventListener(type, listener, options?)` {/*removeeventlistener*/} + +Removes an event listener from all first-level DOM children of the Fragment. + +```js +fragmentRef.current.removeEventListener('click', handleClick); +``` + +##### Parameters {/*removeeventlistener-parameters*/} + +* `type`: The event type string. +* `listener`: The event handler function to remove. +* **optional** `options`: An options object or boolean, matching the [DOM `removeEventListener` API.](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener) + +##### Returns {/*removeeventlistener-returns*/} + +`removeEventListener` does not return anything (`undefined`). + +--- + +#### `dispatchEvent(event)` {/*dispatchevent*/} + +Dispatches an event on the Fragment. Added event listeners are called, and the event can bubble to the Fragment's DOM parent. + +```js +fragmentRef.current.dispatchEvent(new Event('custom', { bubbles: true })); +``` + +##### Parameters {/*dispatchevent-parameters*/} + +* `event`: An [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) object to dispatch. If `bubbles` is `true`, the event bubbles to the Fragment's parent DOM node. + +##### Returns {/*dispatchevent-returns*/} + +`true` if the event was not cancelled, `false` if `preventDefault()` was called. + +--- + +#### `focus(options?)` {/*focus*/} + +Focuses the first focusable DOM node in the Fragment. Unlike calling `element.focus()` on a DOM element, this method searches *all* nested children depth-first until it finds a focusable element—not just the element itself or its direct children. + +```js +fragmentRef.current.focus(); +``` + +##### Parameters {/*focus-parameters*/} + +* **optional** `options`: A [`FocusOptions`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options) object (e.g. `{ preventScroll: true }`). + +##### Returns {/*focus-returns*/} + +`focus` does not return anything (`undefined`). + +--- + +#### `focusLast(options?)` {/*focuslast*/} + +Focuses the last focusable DOM node in the Fragment. Searches nested children depth-first, then iterates in reverse. + +```js +fragmentRef.current.focusLast(); +``` + +##### Parameters {/*focuslast-parameters*/} + +* **optional** `options`: A [`FocusOptions`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options) object. + +##### Returns {/*focuslast-returns*/} + +`focusLast` does not return anything (`undefined`). + +--- + +#### `blur()` {/*blur*/} + +Removes focus from the active element if it is within the Fragment. If `document.activeElement` is not within the Fragment, `blur` does nothing. + +```js +fragmentRef.current.blur(); +``` + +##### Returns {/*blur-returns*/} + +`blur` does not return anything (`undefined`). + +--- + +#### `observeUsing(observer)` {/*observeusing*/} + +Starts observing all first-level DOM children of the Fragment with the provided observer. + +```js +const observer = new IntersectionObserver(callback, options); +fragmentRef.current.observeUsing(observer); +``` + +##### Parameters {/*observeusing-parameters*/} + +* `observer`: An [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) or [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) instance. + +##### Returns {/*observeusing-returns*/} + +`observeUsing` does not return anything (`undefined`). + +--- + +#### `unobserveUsing(observer)` {/*unobserveusing*/} + +Stops observing the Fragment's DOM children with the specified observer. + +```js +fragmentRef.current.unobserveUsing(observer); +``` + +##### Parameters {/*unobserveusing-parameters*/} + +* `observer`: The same `IntersectionObserver` or `ResizeObserver` instance previously passed to [`observeUsing`](#observeusing). + +##### Returns {/*unobserveusing-returns*/} + +`unobserveUsing` does not return anything (`undefined`). + +--- + +#### `getClientRects()` {/*getclientrects*/} + +Returns a flat array of [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) objects representing the bounding rectangles of all first-level DOM children. + +```js +const rects = fragmentRef.current.getClientRects(); +``` + +##### Returns {/*getclientrects-returns*/} + +An `Array<DOMRect>` containing the bounding rectangles of all children. + +--- + +#### `getRootNode(options?)` {/*getrootnode*/} + +Returns the root node containing the Fragment's parent DOM node, matching the behavior of [`Node.getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode). + +```js +const root = fragmentRef.current.getRootNode(); +``` + +##### Parameters {/*getrootnode-parameters*/} + +* **optional** `options`: An object with a `composed` boolean property, matching the [DOM `getRootNode` API.](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode#options) + +##### Returns {/*getrootnode-returns*/} + +A `Document`, `ShadowRoot`, or the `FragmentInstance` itself if there is no parent DOM node. + +--- + +#### `compareDocumentPosition(otherNode)` {/*comparedocumentposition*/} + +Compares the document position of the Fragment with another node, returning a bitmask matching the behavior of [`Node.compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition). + +```js +const position = fragmentRef.current.compareDocumentPosition(otherElement); +``` + +##### Parameters {/*comparedocumentposition-parameters*/} + +* `otherNode`: The DOM node to compare against. + +##### Returns {/*comparedocumentposition-returns*/} + +A bitmask of [position flags](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition#return_value). Empty Fragments and Fragments with children rendered through a [portal](/reference/react-dom/createPortal) include `Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC` in the result. + +--- + +#### `scrollIntoView(alignToTop?)` {/*scrollintoview*/} + +Scrolls the Fragment's children into view. When `alignToTop` is `true` or omitted, scrolls to align the first child with the top of the scrollable ancestor. When `alignToTop` is `false`, scrolls to align the last child with the bottom. + +```js +fragmentRef.current.scrollIntoView(); +``` + +##### Parameters {/*scrollintoview-parameters*/} + +* **optional** `alignToTop`: A boolean. If `true` (the default), scrolls the first child to the top of the scrollable area. If `false`, scrolls the last child to the bottom. Unlike [`Element.scrollIntoView()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView), this method does not accept a `ScrollIntoViewOptions` object. + +##### Returns {/*scrollintoview-returns*/} + +`scrollIntoView` does not return anything (`undefined`). + +##### Caveats {/*scrollintoview-caveats*/} + +* `scrollIntoView` does not accept an options object. Passing one throws an error. Use the `alignToTop` boolean instead. +* When the Fragment has no children, `scrollIntoView` scrolls the nearest sibling or parent into view as a fallback. + +--- + +#### `FragmentInstance` Caveats {/*fragmentinstance-caveats*/} + +* Methods that target children (such as `addEventListener`, `observeUsing`, and `getClientRects`) operate on *first-level host (DOM) children* of the Fragment. They do not directly target children nested inside another DOM element. +* `focus` and `focusLast` search nested children depth-first for focusable elements, unlike event and observer methods which only target first-level host children. +* `observeUsing` does not work on text nodes. React logs a warning in development if the Fragment contains only text children. +* React does not apply event listeners added via `addEventListener` to hidden [`<Activity>`](/reference/react/Activity) trees. When an `Activity` boundary switches from hidden to visible, listeners are applied automatically. +* Each first-level DOM child of a Fragment with a `ref` gets a `reactFragments` property—a `Set<FragmentInstance>` containing all Fragment instances that own the element. This enables [caching a shared observer](#caching-global-intersection-observer) across multiple Fragments. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- @@ -242,47 +502,324 @@ function PostBody({ body }) { --- +<<<<<<< HEAD ### <CanaryBadge /> フラグメント ref を使った DOM とのやり取り {/*using-fragment-refs-for-dom-interaction*/} フラグメント ref を使用すると、余分なラッパ要素を追加することなく、フラグメントでラップされた DOM ノードとやり取りすることができます。これは、イベント処理、可視性追跡、フォーカス管理、そして `ReactDOM.findDOMNode()` のような非推奨のパターンの置き換えに役立ちます。 +======= +### <CanaryBadge /> Adding event listeners without a wrapper element {/*adding-event-listeners-without-wrapper*/} + +Fragment `ref`s let you add event listeners to a group of elements without adding a wrapper DOM node. Use a [ref callback](/reference/react-dom/components/common#ref-callback) to attach and clean up listeners: + +<Sandpack> +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ```js -import { Fragment } from 'react'; +import { Fragment, useState, useRef, useEffect } from 'react'; function ClickableFragment({ children, onClick }) { + const fragmentRef = useRef(null); + useEffect(() => { + const fragmentInstance = fragmentRef.current; + if (fragmentInstance === null) { + return; + } + fragmentInstance.addEventListener('click', onClick); + return () => { + fragmentInstance.removeEventListener( + 'click', + onClick + ); + }; + }, [onClick]) return ( - <Fragment ref={fragmentInstance => { - fragmentInstance.addEventListener('click', handleClick); - return () => fragmentInstance.removeEventListener('click', handleClick); - }}> + <Fragment ref={fragmentRef}> {children} </Fragment> ); } + +export default function App() { + const [clicks, setClicks] = useState(0); + + return ( + <> + <p>Total clicks: {clicks}</p> + <ClickableFragment onClick={() => { + setClicks(c => c + 1); + }}> + <button>Button A</button> + <button>Button B</button> + <button>Button C</button> + </ClickableFragment> + </> + ); +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "canary", + "react-dom": "canary", + "react-scripts": "latest" + } +} ``` + +</Sandpack> + +The `addEventListener` call applies the listener to every first-level DOM child of the Fragment. When children are dynamically added or removed, the `FragmentInstance` automatically adds or removes the listener. + +<DeepDive> + +#### Which children does a Fragment ref target? {/*which-children-does-a-fragment-ref-target*/} + +A `FragmentInstance` targets the **first-level host (DOM) children** of the Fragment. Consider this tree: + +```js +<Fragment ref={ref}> + <div id="A" /> + <Wrapper> + <div id="B"> + <div id="C" /> + </div> + </Wrapper> + <div id="D" /> +</Fragment> +``` + +`Wrapper` is a React component, so the `FragmentInstance` looks through it to find DOM nodes. The targeted children are `A`, `B`, and `D`. `C` is not targeted because it is nested inside the DOM element `B`. + +Methods like `addEventListener`, `observeUsing`, and `getClientRects` operate on these first-level DOM children. `focus` and `focusLast` are different—they search *all* nested children depth-first to find focusable elements. + +</DeepDive> + --- +<<<<<<< HEAD ### <CanaryBadge /> フラグメント ref を使った可視性追跡 {/*tracking-visibility-with-fragment-refs*/} フラグメント ref は、可視性追跡やインターセクション監視に役立ちます。これにより、子コンポーネントがそれぞれ ref を公開せずとも、コンテンツが表示されるようになったタイミングを監視することができます。 +======= +### <CanaryBadge /> Managing focus across a group of elements {/*managing-focus-across-elements*/} -```js {19,21,31-34} -import { Fragment, useRef, useLayoutEffect } from 'react'; +Fragment `ref`s provide `focus`, `focusLast`, and `blur` methods that operate across all DOM nodes within the Fragment: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca + +<Sandpack> + +```js +import { Fragment, useRef } from 'react'; -function VisibilityObserverFragment({ threshold = 0.5, onVisibilityChange, children }) { +function FormFields({ children }) { + const fragmentRef = useRef(null); + + return ( + <> + <div className="buttons"> + <button onClick={() => { + fragmentRef.current.focus(); + }}> + Focus first + </button> + <button onClick={() => { + fragmentRef.current.focusLast(); + }}> + Focus last + </button> + <button onClick={() => { + fragmentRef.current.blur(); + }}> + Blur + </button> + </div> + <Fragment ref={fragmentRef}> + {children} + </Fragment> + </> + ); +} + +// Even though the inputs are deeply nested, +// focus() searches depth-first to find them. +export default function App() { + return ( + <FormFields> + <fieldset> + <legend>Shipping</legend> + <label> + Street: <input name="street" /> + </label> + <label> + City: <input name="city" /> + </label> + </fieldset> + </FormFields> + ); +} +``` + +```css +.buttons { + display: flex; + gap: 8px; + margin-bottom: 10px; +} + +label { + display: inline-block; +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "canary", + "react-dom": "canary", + "react-scripts": "latest" + } +} +``` + +</Sandpack> + +Calling `focus()` focuses the `street` input—even though it is nested inside a `<fieldset>` and `<label>`. `focus()` searches depth-first through all nested children, not just direct children of the Fragment. `focusLast()` does the same in reverse, and `blur()` removes focus if the currently focused element is within the Fragment. + +--- + +### <CanaryBadge /> Scrolling a group of elements into view {/*scrolling-group-into-view*/} + +Use `scrollIntoView` to scroll a Fragment's children into view without a wrapper element. Pass `true` (or omit the argument) to scroll the first child to the top. Pass `false` to scroll the last child to the bottom: + +<Sandpack> + +```js +import { Fragment, useRef } from 'react'; + +function ScrollableSection({ children }) { + const fragmentRef = useRef(null); + + return ( + <> + <div className="buttons"> + <button onClick={() => { + fragmentRef.current.scrollIntoView(); + }}> + Scroll to top + </button> + <button onClick={() => { + fragmentRef.current.scrollIntoView(false); + }}> + Scroll to bottom + </button> + </div> + <div className="container"> + <Fragment ref={fragmentRef}> + {children} + </Fragment> + </div> + </> + ); +} + +const items = []; +for (let i = 1; i <= 25; i++) { + items.push('Item ' + i); +} + +export default function App() { + return ( + <ScrollableSection> + <h3>Section Start</h3> + {items.map((item) => ( + <p key={item}>{item}</p> + ))} + <h3>Section End</h3> + </ScrollableSection> + ); +} +``` + +```css +.buttons { + display: flex; + gap: 8px; + margin-bottom: 10px; +} + +.container { + height: 200px; + overflow-y: auto; + border: 2px solid #c4c4c4; + border-radius: 4px; + padding: 10px; +} + +h3 { + margin: 4px 0; + /* Padding to handle offset of global sticky nav when scrolling for example */ + padding-top: 4em; + color: #1a73e8; +} + +p { + margin: 4px 0; +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "canary", + "react-dom": "canary", + "react-scripts": "latest" + } +} +``` + +</Sandpack> + +--- + +### <CanaryBadge /> Observing visibility without a wrapper element {/*observing-visibility-without-wrapper*/} + +Use `observeUsing` to attach an `IntersectionObserver` to all first-level DOM children of a Fragment. This lets you track visibility without requiring child components to expose `ref`s or adding a wrapper element: + +<Sandpack> + +```js +import { + Fragment, + useRef, + useLayoutEffect, + useState, +} from 'react'; +import Card from './Card'; + +function VisibleGroup({ onVisibilityChange, children }) { const fragmentRef = useRef(null); useLayoutEffect(() => { + const visibleElements = new Set(); const observer = new IntersectionObserver( (entries) => { - onVisibilityChange(entries.some(entry => entry.isIntersecting)) - }, - { threshold } + entries.forEach(e => { + if (e.isIntersecting) { + visibleElements.add(e.target); + } else { + visibleElements.delete(e.target); + } + }); + onVisibilityChange(visibleElements.size > 0); + } ); - - fragmentRef.current.observeUsing(observer); - return () => fragmentRef.current.unobserveUsing(observer); - }, [threshold, onVisibilityChange]); + const fragmentInstance = fragmentRef.current; + fragmentInstance.observeUsing(observer); + return () => { + fragmentInstance.unobserveUsing(observer); + }; + }, [onVisibilityChange]); return ( <Fragment ref={fragmentRef}> @@ -291,20 +828,23 @@ function VisibilityObserverFragment({ threshold = 0.5, onVisibilityChange, child ); } -function MyComponent() { - const handleVisibilityChange = (isVisible) => { - console.log('Component is', isVisible ? 'visible' : 'hidden'); - }; +export default function App() { + const [isVisible, setIsVisible] = useState(true); return ( - <VisibilityObserverFragment onVisibilityChange={handleVisibilityChange}> - <SomeThirdPartyComponent /> - <AnotherComponent /> - </VisibilityObserverFragment> + <div className={isVisible ? 'page visible' : 'page'}> + <div className="filler">Scroll down</div> + <VisibleGroup onVisibilityChange={setIsVisible}> + <Card title="First section" /> + <Card title="Second section" /> + </VisibleGroup> + <div className="filler">Scroll up</div> + </div> ); } ``` +<<<<<<< HEAD このパターンは、エフェクトベースの可視性ロギング(ほとんどの場合アンチパターン)の代替手段です。エフェクトを使うだけでは、レンダーされたコンポーネントがユーザに見えることを保証できません。 --- @@ -312,17 +852,248 @@ function MyComponent() { ### <CanaryBadge /> フラグメント ref を使ったフォーカス管理 {/*focus-management-with-fragment-refs*/} フラグメント ref は、フラグメント内のすべての DOM ノードにわたって機能するフォーカス管理メソッドを提供します。 +======= +```css +.page { + transition: background 0.3s; +} -```js -import { Fragment, useRef } from 'react'; +.page.visible { + background: #d4edda; +} + +.filler { + height: 500px; + display: flex; + align-items: center; + justify-content: center; + color: #aaa; + font-size: 14px; +} + +.card { + padding: 16px; + background: white; + border: 1px solid #ddd; + border-radius: 8px; + margin: 8px 16px; + box-shadow: 0 1px 3px rgba(0,0,0,0.08); + font-weight: 600; + font-size: 14px; +} +``` + +```js src/Card.js hidden +export default function Card({ title }) { + return <div className="card">{title}</div>; +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "canary", + "react-dom": "canary", + "react-scripts": "latest" + } +} +``` + +</Sandpack> + +--- + +### <CanaryBadge /> Caching a global IntersectionObserver {/*caching-global-intersection-observer*/} + +A common performance optimization for sites with many observers is to share a single IntersectionObserver per config and route its entries to the correct callbacks based on which element intersected. Fragment `ref`s support this same pattern through the `reactFragments` property. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca + +Each first-level DOM child of a Fragment with a `ref` has a `reactFragments` property: a `Set` of `FragmentInstance` objects that contain that element. When the shared observer fires, you can use this property to look up which `FragmentInstance` owns the intersecting element and run the right callbacks. + +<Sandpack> + +```js src/App.js active +import { useState, useCallback } from 'react'; +import ObservedGroup from './ObservedGroup'; +import Card from './Card'; + +export default function App() { + const [bgColor, setBgColor] = useState(null); + + const onGreen = useCallback((entry) => { + if (entry.isIntersecting) { + setBgColor('#d4edda'); + } + }, []); + + const onBlue = useCallback((entry) => { + if (entry.isIntersecting) { + setBgColor('#cce5ff'); + } + }, []); -function FocusFragment({ children }) { return ( - <Fragment ref={(fragmentInstance) => fragmentInstance?.focus()}> + <div className="page" style={{ + background: bgColor || 'white', + }}> + <div className="filler">Scroll down</div> + <ObservedGroup onIntersection={onGreen}> + <Card title="Green section" className="green" /> + </ObservedGroup> + <div className="filler" /> + <ObservedGroup onIntersection={onBlue}> + <Card title="Blue section" className="blue" /> + </ObservedGroup> + <div className="filler">Scroll up</div> + </div> + ); +} +``` + +```js src/ObservedGroup.js +import { + Fragment, + useRef, + useLayoutEffect, +} from 'react'; + +const callbackMap = new WeakMap(); +const observerCache = new Map(); + +function getOptionsKey(options) { + const root = options?.root ?? null; + const rootMargin = options?.rootMargin ?? '0px'; + const threshold = options?.threshold ?? 0; + return `${rootMargin}|${threshold}`; +} + +function getSharedObserver( + fragmentInstance, + onIntersection, + options, +) { + // Register this callback for the + // fragment instance. + const existing = + callbackMap.get(fragmentInstance); + callbackMap.set( + fragmentInstance, + existing + ? [...existing, onIntersection] + : [onIntersection], + ); + + const key = getOptionsKey(options); + if (observerCache.has(key)) { + return observerCache.get(key); + } + + const observer = new IntersectionObserver( + (entries) => { + for (const entry of entries) { + // Look up which FragmentInstances own + // this element. + const fragmentInstances = + entry.target.reactFragments; + if (fragmentInstances) { + for (const inst of fragmentInstances) { + const callbacks = + callbackMap.get(inst) || []; + callbacks.forEach(cb => cb(entry)); + } + } + } + }, + options, + ); + + observerCache.set(key, observer); + return observer; +} + +export default function ObservedGroup({ + onIntersection, + options, + children, +}) { + const fragmentRef = useRef(null); + + useLayoutEffect(() => { + const fragmentInstance = fragmentRef.current; + const observer = getSharedObserver( + fragmentInstance, + onIntersection, + options, + ); + fragmentInstance.observeUsing(observer); + return () => { + fragmentInstance.unobserveUsing(observer); + callbackMap.delete(fragmentInstance); + }; + }, [onIntersection, options]); + + return ( + <Fragment ref={fragmentRef}> {children} </Fragment> ); } ``` +<<<<<<< HEAD `focus()` メソッドはフラグメント内の最初のフォーカス可能な要素にフォーカスを当て、`focusLast()` は最後のフォーカス可能な要素にフォーカスを当てます。 +======= +```css +.page { + transition: background 0.3s; +} + +.filler { + height: 500px; + display: flex; + align-items: center; + justify-content: center; + color: #aaa; + font-size: 14px; +} + +.card { + padding: 16px; + background: white; + border: 1px solid #ddd; + border-radius: 8px; + margin: 0 16px; + box-shadow: 0 1px 3px rgba(0,0,0,0.08); + font-weight: 600; + font-size: 14px; +} + +.card.green { + border-left: 3px solid #28a745; +} + +.card.blue { + border-left: 3px solid #007bff; +} +``` + +```js src/Card.js hidden +export default function Card({ title, className }) { + return <div className={'card' + (className ? ' ' + className : '')}>{title}</div>; +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "canary", + "react-dom": "canary", + "react-scripts": "latest" + } +} +``` + +</Sandpack> + +Multiple `ObservedGroup` components with the same options reuse a single `IntersectionObserver`. When either section scrolls into view, the shared observer fires and uses `reactFragments` to route the entry to the correct callback. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 2342ddbbc..11b73fc95 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -23,12 +23,20 @@ title: <Suspense> ### `<Suspense>` {/*suspense*/} +<<<<<<< HEAD #### props {/*props*/} * `children`: レンダーしようとしている実際の UI です。`children` がレンダー中にサスペンド(suspend, 一時中断)すると、サスペンスバウンダリは `fallback` のレンダーに切り替わります。 * `fallback`: 実際の UI がまだ読み込みを完了していない場合に、その代わりにレンダーする代替 UI です。有効な React ノードであれば何でも受け付けますが、現実的には、フォールバックとは軽量なプレースホルダビュー、つまりローディングスピナやスケルトンのようなものです。`children` がサスペンドすると、サスペンスは自動的に `fallback` に切り替わり、データが準備できたら `children` に戻ります。`fallback` 自体がレンダー中にサスペンドした場合、親のサスペンスバウンダリのうち最も近いものがアクティブになります。 +======= +#### Props {/*props*/} +* `children`: The actual UI you intend to render. If `children` suspends while rendering, the Suspense boundary will switch to rendering `fallback`. +* `fallback`: An alternate UI to render in place of the actual UI if it has not finished loading. Any valid React node is accepted, though in practice, a fallback is a lightweight placeholder view, such as a loading spinner or skeleton. Suspense will automatically switch to `fallback` when `children` suspends, and back to `children` when the data is ready. If `fallback` suspends while rendering, it will activate the closest parent Suspense boundary. +* <ExperimentalBadge /> **optional** `defer`: A boolean. When `true`, React may show the `fallback` first and render or stream `children` later, even when nothing in them suspends. Use it for content that is expensive to render. Defaults to `false`. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca #### 注意点 {/*caveats*/} +<<<<<<< HEAD - React は、初回マウントが成功するより前にサスペンドしたレンダーに関しては、一切の state を保持しません。コンポーネントが読み込まれたときに、React はサスペンドしていたツリーのレンダーを最初からやり直します。 - すでにツリーにコンテンツを表示していたサスペンスが再度サスペンドした場合、`fallback` が再び表示されます。しかしその更新が [`startTransition`](/reference/react/startTransition) または [`useDeferredValue`](/reference/react/useDeferredValue) によって引き起こされた場合を除きます。 - 既に表示されているコンテンツが再度サスペンドしたために React がそれを隠す必要が生じた場合、React はコンテンツツリーの[レイアウトエフェクト](/reference/react/useLayoutEffect)をクリーンアップします。コンテンツが再度表示できるようになったら、React はレイアウトエフェクトを再度実行します。これにより、DOM レイアウトを測定するエフェクトがコンテンツが隠れている間に測定を試みないようにします。 @@ -37,6 +45,42 @@ title: <Suspense> --- ## 使用法 {/*usage*/} +======= +- Suspense does not detect when data is fetched inside an Effect or event handler. It only activates in the [cases listed below.](#what-activates-a-suspense-boundary) +- React does not preserve any state for renders that got suspended before they were able to mount for the first time. When the component has loaded, React will retry rendering the suspended tree from scratch. +- If Suspense was displaying content for the tree, but then it suspended again, the `fallback` will be shown again unless the update causing it was caused by [`startTransition`](/reference/react/startTransition) or [`useDeferredValue`](/reference/react/useDeferredValue). +- React reveals suspended content at most once every 300ms, measured from the last reveal. Boundaries that become ready within that window are [revealed together](/blog/2025/10/01/react-19-2#batching-suspense-boundaries-for-ssr) rather than one at a time. +- If React needs to hide the already visible content because it suspended again, it will clean up [layout Effects](/reference/react/useLayoutEffect) in the content tree. When the content is ready to be shown again, React will fire the layout Effects again. This ensures that Effects measuring the DOM layout don't try to do this while the content is hidden. +- React includes under-the-hood optimizations like *Streaming Server Rendering* and *Selective Hydration* that are integrated with Suspense. Read [an architectural overview](https://github.com/reactwg/react-18/discussions/37) and watch [a technical talk](https://www.youtube.com/watch?v=pj5N-Khihgc) to learn more. + +--- + +### What activates a Suspense boundary {/*what-activates-a-suspense-boundary*/} + +A Suspense boundary waits for its content to be ready before revealing it. Any of the following keeps a boundary from revealing its content: + +- Lazy-loading component code with [`lazy`](/reference/react/lazy). +- Reading a Promise with [`use`](/reference/react/use), including data streamed from [Server Components](/reference/rsc/server-components) or loaded through a [Suspense-enabled framework](#suspense-enabled-frameworks). +- Loading a stylesheet rendered with [`<link rel="stylesheet">` and a `precedence` prop.](/reference/react-dom/components/link#special-rendering-behavior) React blocks the boundary until the stylesheet loads, up to a timeout. [See an example below.](#waiting-for-a-stylesheet-to-load) +- Waiting for a large boundary's HTML to arrive during streaming server rendering. Sending HTML takes time, so a boundary with enough content activates even when nothing in it suspends. React reveals the content as the HTML arrives. +- <CanaryBadge /> Loading fonts. Suspense doesn't wait for fonts by default, but a [`<ViewTransition>`](/reference/react/ViewTransition) update waits for new fonts to load, up to a timeout, so text doesn't flash with a fallback font. [See an example below.](#waiting-for-a-font-to-load) +- <CanaryBadge /> Loading images. Suspense doesn't wait for images by default, but during a [`<ViewTransition>`](/reference/react/ViewTransition) update, React blocks the boundary until the image loads, up to a timeout. Adding an `onLoad` handler opts a specific image out. [See an example below.](#waiting-for-an-image-to-load) +- <ExperimentalBadge /> Performing CPU-bound render work inside a [`<Suspense defer>`](#props) boundary. + +<Note> + +#### Suspense-enabled frameworks {/*suspense-enabled-frameworks*/} + +A *Suspense-enabled framework* gives you a way to read data in your component in a way that activates the closest Suspense boundary. The exact way you load your data depends on your framework, and you'll find the details in its documentation. Under the hood, a Suspense-enabled framework maintains a cache of Promises and calls [`use`](/reference/react/use) to suspend on a Promise. + +Without a framework, you can read a Promise with `use` directly, as long as the Promise is [cached so the same instance is reused across renders.](/reference/react/use#caching-promises-for-client-components) + +</Note> + +--- + +## Usage {/*usage*/} +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ### コンテンツの読み込み中にフォールバックを表示する {/*displaying-a-fallback-while-content-is-loading*/} @@ -203,8 +247,9 @@ async function getAlbums() { </Sandpack> -<Note> +By contrast, code that fetches data outside of `use`, such as inside an Effect, does not activate the boundary: +<<<<<<< HEAD **サスペンスコンポーネントをアクティブ化できるのはサスペンス対応のデータソースだけです**。これには以下が含まれます: - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) や [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) のようなサスペンス対応のフレームワークでのデータフェッチ @@ -216,8 +261,256 @@ async function getAlbums() { 上記の `Albums` コンポーネントで実際にデータをロードする方法は、使用するフレームワークによって異なります。サスペンス対応のフレームワークを使用している場合、詳細はデータフェッチに関するドキュメンテーション内に記載されているはずです。 使い方の規約のある (opinionated) フレームワークを使用せずにサスペンスを使ったデータフェッチを行うことは、まだサポートされていません。サスペンス対応のデータソースを実装するための要件はまだ不安定であり、ドキュメント化されていません。データソースをサスペンスと統合するための公式な API は、React の将来のバージョンでリリースされる予定です。 +======= +<Sandpack> -</Note> +```js src/App.js hidden +import { useState } from 'react'; +import ArtistPage from './ArtistPage.js'; + +export default function App() { + const [show, setShow] = useState(false); + if (show) { + return ( + <ArtistPage + artist={{ + id: 'the-beatles', + name: 'The Beatles', + }} + /> + ); + } else { + return ( + <button onClick={() => setShow(true)}> + Open The Beatles artist page + </button> + ); + } +} +``` + +```js src/ArtistPage.js active +import { Suspense } from 'react'; +import EffectAlbums from './EffectAlbums.js'; + +export default function ArtistPage({ artist }) { + return ( + <> + <h1>{artist.name}</h1> + <Suspense fallback={<Loading />}> + <EffectAlbums artistId={artist.id} /> + </Suspense> + </> + ); +} +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca + +function Loading() { + return <h2>🌀 Loading...</h2>; +} +``` + +```js src/EffectAlbums.js +import { useState, useEffect } from 'react'; +import { fetchData } from './data.js'; + +export default function EffectAlbums({ artistId }) { + const [albums, setAlbums] = useState([]); + + useEffect(() => { + let active = true; + fetchData(`/${artistId}/albums`).then(result => { + if (active) { + setAlbums(result); + } + }); + return () => { + active = false; + }; + }, [artistId]); + + // Suspense can't see this fetch, so its fallback never + // shows. The list stays empty until the data arrives. + return ( + <ul> + {albums.map(album => ( + <li key={album.id}> + {album.title} ({album.year}) + </li> + ))} + </ul> + ); +} +``` + +```js src/data.js hidden +// Note: the way you would do data fetching depends on +// the framework that you use together with Suspense. +// Normally, the caching logic would be inside a framework. + +let cache = new Map(); + +export function fetchData(url) { + if (!cache.has(url)) { + cache.set(url, getData(url)); + } + return cache.get(url); +} + +async function getData(url) { + if (url === '/the-beatles/albums') { + return await getAlbums(); + } else { + throw Error('Not implemented'); + } +} + +async function getAlbums() { + // Add a fake delay to make waiting noticeable. + await new Promise(resolve => { + setTimeout(resolve, 3000); + }); + + return [{ + id: 13, + title: 'Let It Be', + year: 1970 + }, { + id: 12, + title: 'Abbey Road', + year: 1969 + }, { + id: 11, + title: 'Yellow Submarine', + year: 1969 + }, { + id: 10, + title: 'The Beatles', + year: 1968 + }, { + id: 9, + title: 'Magical Mystery Tour', + year: 1967 + }, { + id: 8, + title: 'Sgt. Pepper\'s Lonely Hearts Club Band', + year: 1967 + }, { + id: 7, + title: 'Revolver', + year: 1966 + }, { + id: 6, + title: 'Rubber Soul', + year: 1965 + }, { + id: 5, + title: 'Help!', + year: 1965 + }, { + id: 4, + title: 'Beatles For Sale', + year: 1964 + }, { + id: 3, + title: 'A Hard Day\'s Night', + year: 1964 + }, { + id: 2, + title: 'With The Beatles', + year: 1963 + }, { + id: 1, + title: 'Please Please Me', + year: 1963 + }]; +} +``` + +</Sandpack> + +During streaming server rendering, a boundary also activates while its HTML is still streaming in. With any streaming server rendering API, React sends [the shell](/reference/react-dom/server/renderToPipeableStream#specifying-what-goes-into-the-shell) with the `fallback` first, then streams in each boundary's HTML and swaps out its `fallback` as that content arrives. Press "Render the page" to watch the page stream in: + +<Sandpack> + +```js src/App.js hidden +``` + +```html public/index.html +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <title>Streaming SSR + + + +

+ + + +``` + +```js src/index.js +import { flushReadableStreamToFrame } from './demo-helpers.js'; +import { Suspense, use } from 'react'; +import { renderToReadableStream } from 'react-dom/server'; + +let posts = null; + +function Posts() { + const text = use(posts.promise); + return

{text}

; +} + +function ProfilePage() { + return ( + + +

Alice

+

Photographer and traveler.

+ ⌛ Loading posts...

}> + +
+ + + ); +} + +async function main(frame) { + posts = Promise.withResolvers(); + const stream = await renderToReadableStream(); + + // The posts resolve after the shell has streamed, so React + // streams their HTML in and swaps out the fallback. + setTimeout(() => { + posts.resolve( + 'Just got back from two weeks along the coast. The drive ' + + 'was longer than expected, but every stop was worth it. ' + + 'A full write-up and more photos are coming soon.' + ); + }, 1500); + + await flushReadableStreamToFrame(stream, frame); +} + +document.getElementById('render').addEventListener('click', () => { + main(document.getElementById('container')); +}); +``` + +```js src/demo-helpers.js hidden +export async function flushReadableStreamToFrame(readable, frame) { + const doc = frame.contentWindow.document; + const decoder = new TextDecoder(); + for await (const chunk of readable) { + doc.write(decoder.decode(chunk, { stream: true })); + } + doc.close(); +} +``` + + --- @@ -1992,15 +2285,108 @@ main { ### ナビゲーション時にサスペンスバウンダリをリセットする {/*resetting-suspense-boundaries-on-navigation*/} +<<<<<<< HEAD トランジション中、React は既に表示されているコンテンツを隠さないようにします。しかし、異なるパラメータを持つルートに移動する場合、React にそれが*異なる*コンテンツであると伝えたいことがあります。これを表現するために、`key` が使えます。 +======= +During a Transition, React avoids hiding already revealed content. However, when you navigate to *different* content, such as another user's profile, you'll want the boundary to show the fallback instead of the previous content. You can express this with a `key`: +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ```js ``` +<<<<<<< HEAD 単一のユーザのプロフィールページ内を閲覧していて、何かがサスペンドすると想像してみてください。その更新がトランジションでラップされている場合、既に表示されているコンテンツのフォールバックをトリガしません。これは期待される動作です。 しかし、2 人の異なるユーザのプロフィール間を移動していると想像してみてください。その場合は、フォールバックを表示することが理にかなっています。例えば、あるユーザのタイムラインは別のユーザのタイムラインとは*異なるコンテンツ*です。`key` を指定することで、React は異なるユーザのプロフィールを異なるコンポーネントとして扱うので、ナビゲーション中にサスペンスバウンダリをリセットします。サスペンスを統合したルータは、これを自動的に行うべきです。 +======= +With a different `key`, React treats the profiles as different content and resets the Suspense boundary during navigation. The `key` can go on the boundary itself or on a component above it. Suspense-integrated routers should do this automatically. + +In the example below, opening the profile page loads the first profile. Pressing "Bob" navigates to a different profile, and the `key` resets the boundary, so the fallback shows instead of the previous user's bio. Try removing the `key`: the previous bio stays visible while the next one loads: + + + +```js src/App.js hidden +import { useState } from 'react'; +import ProfilePage from './ProfilePage.js'; + +export default function App() { + const [show, setShow] = useState(false); + if (show) { + return ; + } + return ( + + ); +} +``` + +```js src/ProfilePage.js active +import { Suspense, useState, startTransition } from 'react'; +import Bio from './Bio.js'; +import { fetchBio } from './data.js'; + +export default function ProfilePage() { + const [user, setUser] = useState(() => ({ + id: 'alice', + bioPromise: fetchBio('alice'), + })); + function navigate(id) { + startTransition(() => { + setUser({ id, bioPromise: fetchBio(id) }); + }); + } + return ( + <> + + + ⌛ Loading profile...

}> + +
+ + ); +} +``` + +```js src/Bio.js +import { use } from 'react'; + +export default function Bio({ bioPromise }) { + const bio = use(bioPromise); + return

{bio}

; +} +``` + +```js src/data.js hidden +// Note: the way you would do data fetching depends on +// the framework that you use together with Suspense. + +export async function fetchBio(userId) { + // Add a fake delay to make waiting noticeable. + await new Promise(resolve => { + setTimeout(resolve, 1500); + }); + + return userId === 'alice' + ? 'Alice is a photographer and traveler.' + : 'Bob collects vintage synthesizers.'; +} +``` + +```css +button { + margin-right: 8px; +} +``` + +
+>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca --- @@ -2029,7 +2415,876 @@ function Chat() { --- +<<<<<<< HEAD ## トラブルシューティング {/*troubleshooting*/} +======= +### Waiting for a stylesheet to load {/*waiting-for-a-stylesheet-to-load*/} + +A stylesheet rendered with [`` and a `precedence` prop](/reference/react-dom/components/link#special-rendering-behavior) blocks the Suspense boundary until the stylesheet loads, up to a timeout, so the content doesn't appear unstyled. + +In the example below, the `Card` component renders a stylesheet with `precedence`. Press "Show card": React shows the fallback until the stylesheet has loaded, and then reveals the card with its styles applied. + +For comparison, the second button performs the same update without React, in a separate document. Nothing waits for the stylesheet, so the card's text appears in a fallback font first and then switches: + + + +```js +import { Suspense, useState, startTransition } from 'react'; +import { freshStylesheetUrl } from './styles.js'; +import VanillaCard from './VanillaCard.js'; + +function Card({ href }) { + return ( + <> + +
This card uses a font from the stylesheet.
+ + ); +} + +export default function App() { + const [href, setHref] = useState(null); + return ( + <> + + {href && ( + ⌛ Loading styles...

}> + +
+ )} +
+ + + ); +} +``` + +```js src/VanillaCard.js +import { useRef } from 'react'; +import { freshStylesheetUrl } from './styles.js'; + +export default function VanillaCard() { + const ref = useRef(null); + function show() { + const doc = ref.current.contentWindow.document; + doc.open(); + doc.write(` + +
This card uses a font from the stylesheet.
+ + `); + doc.close(); + } + return ( + <> + +