diff --git a/.claude/skills/docs-writer-blog/SKILL.md b/.claude/skills/docs-writer-blog/SKILL.md index ef28225f81..baa21c34d9 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 5ebcdee37d..c252f6ce0a 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 63e310e0ba..de2bfc3625 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 2f5b2a497e..97f8d183b1 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 f9b3328ee5..4cb6fbc712 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 92626a1e63..ed9efe38d0 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 6e25584669..d8d2ce3325 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}\"", @@ -51,6 +51,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", @@ -102,6 +103,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 0000000000..9d0cff450f 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 0000000000..3fbdb483db 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 0000000000..10476e5e88 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 0000000000..c66a5cd6db 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 0000000000..0100fa16b6 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 0000000000..a90bec66eb 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 0000000000..e806a103b8 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 0000000000..0f79e181d5 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 0000000000..9f87e7efbf 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 0000000000..a4de758019 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 0000000000..1f63907eab 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 0000000000..94d96f6703 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 0000000000..0e03ecb779 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 0000000000..a67e30b1b0 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 0000000000..4d5a5e8303 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 0000000000..459c267e45 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 0000000000..7887765b48 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 0000000000..23a950103c 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 0000000000..7694a7fb69 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 0000000000..d0debc5bee 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 0000000000..c769056152 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 0000000000..57b50c800a 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 1f7ebd500e..0000000000 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 0000000000..90ce0770ee 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 0000000000..5c623e6a73 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 dd1e1aa61e..0000000000 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 0000000000..093a363fb9 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 46a21cdc9e..287dde36ae 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 0000000000..937727a1cb --- /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 bd98d5b38e..dff09ed3a7 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 01f0ae336f..6599e03abc 100644 --- a/src/components/Layout/Footer.tsx +++ b/src/components/Layout/Footer.tsx @@ -348,8 +348,13 @@ export function Footer() { <FooterLink href="/community" isHeader={true}> Comunidade </FooterLink> +<<<<<<< HEAD <FooterLink href="https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md"> Código de Conduta +======= + <FooterLink href="https://github.com/react/react/blob/main/CODE_OF_CONDUCT.md"> + Code of Conduct +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </FooterLink> <FooterLink href="/community/team">Conheça o Time</FooterLink> <FooterLink href="/community/docs-contributors"> @@ -390,7 +395,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 aa39fe5fc2..59cf4386d8 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 e2e2169fd5..5f9bd6a5ed 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 c40bbf7ea1..b2354fd24c 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 9e87a93bfb..7e47360a77 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 b51627d89b..cb5d4e842c 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 2d0c65537e..2716fa2d1f 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 924e6e09ee..8048953693 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 3d44d0ccca..33633d7102 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 @@ Todos podem ler as discussões no [repositório do React 18 Working Group](https Como esperamos um aumento inicial de interesse no Grupo de Trabalho, apenas os membros convidados poderão criar ou comentar em tópicos. No entanto, os tópicos são totalmente visíveis ao público, para que todos tenham acesso às mesmas informações. Acreditamos que este é um bom compromisso entre a criação de um ambiente produtivo para os membros do grupo de trabalho, mantendo a transparência com a comunidade em geral. +<<<<<<< HEAD Como sempre, você pode enviar relatórios de erros, perguntas e feedback geral para nosso [rastreador de problemas](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 ## Como experimentar o React 18 Alpha hoje {/*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 541236ec5d..549f1780ee 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 @@ description: Como compartilhamos na publicação, React 18 apresenta novos recur Como compartilhamos no [post de lançamento](/blog/2022/03/29/react-v18), React 18 apresenta recursos impulsionados por nosso novo renderizador concorrente, com uma estratégia de adoção gradual para aplicativos existentes. Neste artigo, vamos guiá-lo através das etapas para a atualização para o React 18. +<<<<<<< HEAD Por favor, [relate quaisquer problemas](https://github.com/facebook/react/issues/new/choose) que você encontrar ao atualizar para React 18. +======= +Please [report any issues](https://github.com/react/react/issues/new/choose) you encounter while upgrading to React 18. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Intro> @@ -314,11 +318,19 @@ Se você precisar oferecer suporte ao Internet Explorer, recomendamos que você ### React {/*react*/} +<<<<<<< HEAD * **Os componentes agora podem renderizar `undefined`:** O React não avisa mais se você retornar `undefined` de um componente. Isso torna os valores de retorno de componentes permitidos consistentes com os valores que são permitidos no meio de uma árvore de componentes. Sugerimos o uso de um linter para evitar erros como esquecer uma declaração `return` antes do JSX. * **Em testes, os avisos `act` agora são opt-in:** Se você estiver executando testes ponta a ponta, os avisos `act` são desnecessários. Introduzimos um mecanismo [opt-in](https://github.com/reactwg/react-18/discussions/102) para que você possa habilitá-los apenas para testes de unidade, onde são úteis e benéficos. * **Sem aviso sobre `setState` em componentes desmontados:** Anteriormente, o React avisava sobre vazamentos de memória quando você chamava `setState` em um componente desmontado. Este aviso foi adicionado para assinaturas, mas as pessoas encontram principalmente isso em cenários em que a configuração do state está ok, e as soluções alternativas tornam o código pior. [Removemos](https://github.com/facebook/react/pull/22114) este aviso. * **Sem supressão de logs do console:** Quando você usa o Modo estrito, o React renderiza cada componente duas vezes para ajudá-lo a encontrar efeitos colaterais inesperados. No React 17, suprimimos os logs do console para uma das duas renderizações para facilitar a leitura dos logs. Em resposta ao [feedback da comunidade](https://github.com/facebook/react/issues/21783) sobre isso ser confuso, removemos a supressão. Em vez disso, se você tiver o React DevTools instalado, as renderizações do segundo log serão exibidas em cinza e haverá uma opção (desativada por padrão) para suprimi-las completamente. * **Uso de memória aprimorado:** O React agora limpa mais campos internos na desmontagem, tornando o impacto de vazamentos de memória não corrigidos que podem existir no código do seu aplicativo menos grave. +======= +* **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*/} @@ -327,4 +339,8 @@ Se você precisar oferecer suporte ao Internet Explorer, recomendamos que você ## Changelog {/*changelog*/} -Você pode visualizar o [changelog completo aqui](https://github.com/facebook/react/blob/main/CHANGELOG.md). \ No newline at end of file +<<<<<<< HEAD +Você pode visualizar o [changelog completo aqui](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 4c3d6fa1e1..8230a64f83 100644 --- a/src/content/blog/2022/03/29/react-v18.md +++ b/src/content/blog/2022/03/29/react-v18.md @@ -265,6 +265,7 @@ Veja [Como Atualizar para o React 18](/blog/2022/03/08/react-18-upgrade-guide) p ### React {/*react*/} +<<<<<<< HEAD * Adiciona `useTransition` e `useDeferredValue` para separar atualizações urgentes de transições. ([#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) por [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), [@rickhanlonii](https://github.com/rickhanlonii), e [@sebmarkbage](https://github.com/sebmarkbage)) * Adiciona `useId` para gerar IDs únicos. ([#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) por [@acdlite](https://github.com/acdlite), [@lunaruan](https://github.com/lunaruan), e [@sebmarkbage](https://github.com/sebmarkbage)) * Adiciona `useSyncExternalStore` para ajudar bibliotecas de lojas externas a se integrarem com o 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) por [@acdlite](https://github.com/acdlite), [@bvaughn](https://github.com/bvaughn), e [@drarmstr](https://github.com/drarmstr)) @@ -337,3 +338,77 @@ Veja [Como Atualizar para o React 18](/blog/2022/03/08/react-18-upgrade-guide) p * Atualiza o plugin webpack para webpack 5 ([#22739](https://github.com/facebook/react/pull/22739) por [@michenly](https://github.com/michenly)) * Corrige um erro no carregador do Node. ([#22537](https://github.com/facebook/react/pull/22537) por [@btea](https://github.com/btea)) * Usa `globalThis` em vez de `window` para ambientes de borda. ([#22777](https://github.com/facebook/react/pull/22777) por [@huozhi](https://github.com/huozhi)) +======= +* 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/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/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/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/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/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)) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca 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 195e70b233..faed985474 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 @@ Atualmente, o React possui duas ferramentas de profiling. O [Profiler original]( Percebemos que os desenvolvedores não acham muito útil saber sobre commits lentos individuais ou componentes fora de contexto. É mais útil saber o que realmente causa os commits lentos. E que os desenvolvedores querem ser capazes de rastrear interações específicas (por exemplo, um clique de botão, um carregamento inicial ou uma navegação de página) para observar regressões de desempenho e entender por que uma interação foi lenta e como corrigi-la. +<<<<<<< HEAD Anteriormente, tentamos resolver esse problema criando uma [API de Rastreamento de Interação](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16), mas ela tinha algumas falhas de design fundamentais que reduziram a precisão do rastreamento de por que uma interação era lenta e, às vezes, resultavam em interações que nunca terminavam. Acabamos [removendo essa API](https://github.com/facebook/react/pull/20037) devido a esses problemas. +======= +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 Estamos trabalhando em uma nova versão para a API de Rastreamento de Interação (provisoriamente chamada de Rastreamento de Transições, pois é iniciada via `startTransition`) que resolve esses problemas. 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 1823ebdfbd..6f918a2a97 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,7 @@ To help make the upgrade to React 19 easier, we've published a `react@18.3` rele We recommend upgrading to React 18.3 first to help identify any issues before upgrading to React 19. -For a list of changes in 18.3 see the [Release Notes](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). </Note> @@ -38,7 +38,7 @@ In this post, we will guide you through the steps for upgrading to React 19: - [TypeScript changes](#typescript-changes) - [Changelog](#changelog) -If you'd like to help us test React 19, follow the steps in this upgrade guide and [report any issues](https://github.com/facebook/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). +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). --- ## Installing {/*installing*/} @@ -256,7 +256,7 @@ class Child extends React.Component { #### Removed: string refs {/*removed-string-refs*/} String refs were deprecated in [March, 2018 (v16.3.0)](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html). -Class components supported string refs before being replaced by ref callbacks due to [multiple downsides](https://github.com/facebook/react/issues/1373). In React 19, we're removing string refs to make React simpler and easier to understand. +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. If you're still using string refs in class components, you'll need to migrate to ref callbacks: @@ -730,24 +730,24 @@ const reducer = (state: State, action: Action) => state; ### Other breaking changes {/*other-breaking-changes*/} -- **react-dom**: Error for javascript URLs in `src` and `href` [#26507](https://github.com/facebook/react/pull/26507) -- **react-dom**: Remove `errorInfo.digest` from `onRecoverableError` [#28222](https://github.com/facebook/react/pull/28222) -- **react-dom**: Remove `unstable_flushControlled` [#26397](https://github.com/facebook/react/pull/26397) -- **react-dom**: Remove `unstable_createEventHandle` [#28271](https://github.com/facebook/react/pull/28271) -- **react-dom**: Remove `unstable_renderSubtreeIntoContainer` [#28271](https://github.com/facebook/react/pull/28271) -- **react-dom**: Remove `unstable_runWithPriority` [#28271](https://github.com/facebook/react/pull/28271) -- **react-is**: Remove deprecated methods from `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) ### Other notable changes {/*other-notable-changes*/} -- **react**: Batch sync, default and continuous lanes [#25700](https://github.com/facebook/react/pull/25700) -- **react**: Don't prerender siblings of suspended component [#26380](https://github.com/facebook/react/pull/26380) -- **react**: Detect infinite update loops caused by render phase updates [#26625](https://github.com/facebook/react/pull/26625) -- **react-dom**: Transitions in popstate are now synchronous [#26025](https://github.com/facebook/react/pull/26025) -- **react-dom**: Remove layout effect warning during SSR [#26395](https://github.com/facebook/react/pull/26395) -- **react-dom**: Warn and don’t set empty string for src/href (except anchor tags) [#28124](https://github.com/facebook/react/pull/28124) +- **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/facebook/react/blob/main/CHANGELOG.md#1900-december-5-2024). +For a full list of changes, please see the [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md#1900-december-5-2024). --- 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 8264ecae3c..9a9a515303 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 @@ Em seguida, na palestra principal, [Josh Story](https://twitter.com/joshcstory) - [React for Two Computers](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=18825s) por [Dan Abramov](https://bsky.app/profile/danabra.mov) - [And Now You Understand React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY&t=11256s) por [Kent C. Dodds](https://twitter.com/kentcdodds) +<<<<<<< HEAD Finalmente, encerramos a palestra principal com [Joe Savona](https://twitter.com/en_JS), [Sathya Gunasekaran](https://twitter.com/_gsathya) e [Mofei Zhang](https://twitter.com/zmofei) anunciando que o React Compiler agora é [Open Source](https://github.com/facebook/react/pull/29061) e compartilhando uma versão experimental do React Compiler para experimentar. +======= +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 Para obter mais informações sobre como usar o Compiler e como ele funciona, confira [os documentos](/learn/react-compiler) e estas palestras: 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 8ac03ec564..87e4737166 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 @@ -91,7 +91,11 @@ Como seu código é pré-compilado, os usuários de sua biblioteca não precisar Anunciamos anteriormente o [Grupo de Trabalho do React Compiler](https://github.com/reactwg/react-compiler), apenas por convite, na React Conf para fornecer feedback, fazer perguntas e colaborar no lançamento experimental do compilador. +<<<<<<< HEAD A partir de hoje, juntamente com o lançamento Beta do React Compiler, estamos abrindo a adesão ao Grupo de Trabalho para todos. O objetivo do Grupo de Trabalho do React Compiler é preparar o ecossistema para uma adoção suave e gradual do React Compiler por aplicativos e bibliotecas existentes. Por favor, continue enviando relatórios de bugs no [repositório do React](https://github.com/facebook/react), mas deixe seus feedbacks, perguntas ou ideias no [fórum de discussão do Grupo de Trabalho](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 A equipe principal também usará o repositório de discussões para compartilhar nossas descobertas de pesquisa. À medida que o Lançamento Estável se aproxima, qualquer informação importante também será postada neste fórum. @@ -126,7 +130,11 @@ Obrigado a [Sathya Gunasekaran](https://twitter.com/_gsathya), [Joe Savona](http --- +<<<<<<< HEAD [^1]: Obrigado a [@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) e vários outros por suas contribuições para o compilador. +======= +[^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]: Obrigado a [Vaishali Garg](https://www.linkedin.com/in/vaishaligarg09) por liderar este estudo sobre o React Compiler na Meta e por revisar este post. diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md index 7496464588..93ac0c3601 100644 --- a/src/content/blog/2024/12/05/react-19.md +++ b/src/content/blog/2024/12/05/react-19.md @@ -182,7 +182,7 @@ const [error, submitAction, isPending] = useActionState( `React.useActionState` was previously called `ReactDOM.useFormState` in the Canary releases, but we've renamed it and deprecated `useFormState`. -See [#28491](https://github.com/facebook/react/pull/28491) for more info. +See [#28491](https://github.com/react/react/pull/28491) for more info. </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 9b6095f8b2..dbd673a291 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,7 @@ root.render( If you're curious to know more about how they work, check out [How Does `<ViewTransition>` Work](/reference/react/ViewTransition#how-does-viewtransition-work) in the docs. -_For more background on how we built View Transitions, see: [#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), and [#32038](https://github.com/facebook/react/pull/32038) by [@sebmarkbage](https://twitter.com/sebmarkbage) (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!)._ --- 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 51c30f70a2..feee6cdb62 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,7 @@ To continue using the legacy config, you can change to `recommended-legacy`: For a full list of compiler enabled rules, [check out the linter docs](/reference/eslint-plugin-react-hooks#recommended). -Check out the `eslint-plugin-react-hooks` [changelog for a full list of changes](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). --- @@ -315,23 +315,23 @@ The original intent of using a special character that was not valid for CSS sele ## Changelog {/*changelog*/} Other notable changes -- `react-dom`: Allow nonce to be used on hoistable styles [#32461](https://github.com/facebook/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/facebook/react/pull/32774) +- `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/facebook/react/pull/33507) -- `react`: Fix infinite useDeferredValue loop in popstate event [#32821](https://github.com/facebook/react/pull/32821) -- `react`: Fix a bug when an initial value was passed to useDeferredValue [#34376](https://github.com/facebook/react/pull/34376) -- `react`: Fix a crash when submitting forms with Client Actions [#33055](https://github.com/facebook/react/pull/33055) -- `react`: Hide/unhide the content of dehydrated suspense boundaries if they resuspend [#32900](https://github.com/facebook/react/pull/32900) -- `react`: Avoid stack overflow on wide trees during Hot Reload [#34145](https://github.com/facebook/react/pull/34145) -- `react`: Improve component stacks in various places [#33629](https://github.com/facebook/react/pull/33629), [#33724](https://github.com/facebook/react/pull/33724), [#32735](https://github.com/facebook/react/pull/32735), [#33723](https://github.com/facebook/react/pull/33723) -- `react`: Fix a bug with React.use inside React.lazy-ed Component [#33941](https://github.com/facebook/react/pull/33941) -- `react-dom`: Stop warning when ARIA 1.3 attributes are used [#34264](https://github.com/facebook/react/pull/34264) -- `react-dom`: Fix a bug with deeply nested Suspense inside Suspense fallbacks [#33467](https://github.com/facebook/react/pull/33467) -- `react-dom`: Avoid hanging when suspending after aborting while rendering [#34192](https://github.com/facebook/react/pull/34192) - -For a full list of changes, please see the [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md). +- `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). --- 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 14bb0f265a..1c676eaa28 100644 --- a/src/content/blog/2025/10/07/react-compiler-1.md +++ b/src/content/blog/2025/10/07/react-compiler-1.md @@ -131,7 +131,11 @@ export default defineConfig([ } ``` +<<<<<<< HEAD Para habilitar as regras do React Compiler, recomendamos usar o preset `recommended`. Você também pode conferir o [README](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md) para mais instruções. Aqui estão alguns exemplos que apresentamos no 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 - Capturando padrões de `setState` que causam loops de renderização com [`set-state-in-render`](/reference/eslint-plugin-react-hooks/lints/set-state-in-render). - Sinalizando trabalho caro dentro de efeitos via [`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 ea92d7cbd3..66a11c42c9 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 @@ -33,7 +33,11 @@ A vulnerabilidade está presente nas versões 19.0, 19.1.0, 19.1.1 e 19.2.0 de: ## Ação Imediata Necessária {/*immediate-action-required*/} +<<<<<<< HEAD Uma correção foi introduzida nas versões [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) e [19.2.1](https://github.com/facebook/react/releases/tag/v19.2.1). Se você estiver usando algum dos pacotes acima, atualize para qualquer uma das versões corrigidas imediatamente. +======= +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 Se o código React do seu aplicativo não usa um servidor, seu aplicativo não é afetado por esta vulnerabilidade. Se seu aplicativo não usa um framework, bundler ou plugin de bundler que suporte Componentes de Servidor do React, seu aplicativo não é afetado por esta vulnerabilidade. @@ -192,7 +196,11 @@ Se você estiver usando React Native em um monorepo, você deve atualizar _apena Isso é necessário para mitigar o aviso de segurança, mas você não precisa atualizar `react` e `react-dom`, então isso não causará o erro de incompatibilidade de versão no React Native. +<<<<<<< HEAD Veja [este issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) para mais informações. +======= +See [this issue](https://github.com/react/react-native/issues/54772#issuecomment-3617929832) for more information. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ## Cronologia {/*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 c28600ccf9..02c92c8fed 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 @@ -96,7 +96,11 @@ Se você estiver usando React Native em um monorepo, você deve atualizar _apena Isso é necessário para mitigar os avisos de segurança, mas você não precisa atualizar `react` e `react-dom`, então isso não causará o erro de incompatibilidade de versão no React Native. +<<<<<<< HEAD Veja [este issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) para mais informações. +======= +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 ab4b10d0a2..0e1c6cc0c8 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -150,7 +150,11 @@ A equipe do React está animada para compartilhar algumas atualizações: ### Todas as notas de lançamento {/*all-release-notes*/} +<<<<<<< HEAD Nem todo lançamento do React merece um post próprio, mas você pode encontrar um changelog detalhado para cada lançamento no arquivo [`CHANGELOG.md`](https://github.com/facebook/react/blob/main/CHANGELOG.md) no repositório do React, bem como na página [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 837cd6d8fa..a5ab03aa7c 100644 --- a/src/content/community/acknowledgements.md +++ b/src/content/community/acknowledgements.md @@ -4,7 +4,11 @@ title: Reconhecimentos <Intro> +<<<<<<< HEAD O React foi originalmente criado por [Jordan Walke.](https://github.com/jordwalke) Hoje, o React tem uma [equipe dedicada em tempo integral trabalhando nele](/community/team), bem como mais de mil [colaboradores de código aberto.](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/index.md b/src/content/community/index.md index e8de6e8375..9bf2b23138 100644 --- a/src/content/community/index.md +++ b/src/content/community/index.md @@ -10,7 +10,11 @@ React tem uma comunidade de milhões de desenvolvedores. Nesta página nós list ## Código de Conduta {/*code-of-conduct*/} +<<<<<<< HEAD Antes de participar das comunidades do React, [leia nosso Código de Conduta.](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md) Adotamos o [Acordo do Colaborador](https://www .contributor-covenant.org/) e esperamos que todos os membros da comunidade sigam as diretrizes nele contidas. +======= +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 5a39087cac..1c6b64d6e1 100644 --- a/src/content/community/team.md +++ b/src/content/community/team.md @@ -4,12 +4,17 @@ title: "Conheça a Equipe" <Intro> +<<<<<<< HEAD O desenvolvimento do React é liderado por uma equipe dedicada que trabalha em tempo integral na Meta. Ele também recebe contribuições de pessoas de todo o mundo. +======= +React development is led by contributors from companies and communities all over the world. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca </Intro> -## React Core {/*react-core*/} +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. +<<<<<<< HEAD Os membros da equipe React Core trabalham em tempo integral nas APIs do componente core, no mecanismo que alimenta React DOM e React Native, React DevTools e no site da documentação do React. Os membros atuais da equipe React estão listados em ordem alfabética abaixo. @@ -32,12 +37,122 @@ Os membros atuais da equipe React estão listados em ordem alfabética abaixo. <TeamMember name="Jack Pope" permalink="jack-pope" photo="/images/team/jack-pope.jpg" github="jackpope" personal="jackpope.me" title="Engineer at Meta"> Pouco depois de ser apresentado ao AutoHotkey, Jack escreveu scripts para automatizar tudo o que conseguia imaginar. Ao atingir as limitações, ele mergulhou de cabeça no desenvolvimento de aplicativos da web e não olhou para trás. Mais recentemente, Jack trabalhou na plataforma web do Instagram antes de mudar para React. Sua linguagem de programação favorita é JSX. +======= +## 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 abandonou o C embarcado para uma carreira em engenharia front-end e nunca mais olhou para trás. Munido de conhecimento esotérico de CSS e uma paixão por UI bonita, Jason entrou no Facebook em 2010, onde agora se sente privilegiado por ter visto o desenvolvimento do JavaScript amadurecer. Embora ele possa não entender como os loops `for...of` funcionam, ele adora trabalhar com pessoas brilhantes em projetos que possibilitam uma UX incrível. </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 planejava se formar em matemática e filosofia, mas entrou na ciência da computação depois de escrever simulações de física no Matlab. Antes do React, ele trabalhou no Relay, RSocket.js e na linguagem de programação Skip. Embora ele não esteja construindo algum tipo de sistema reativo, ele gosta de correr, estudar japonês e passar tempo com sua família. </TeamMember> @@ -46,6 +161,7 @@ Os membros atuais da equipe React estão listados em ordem alfabética abaixo. Jordan começou a programar construindo aplicativos para iPhone, onde estava empurrando e retirando view controllers antes de saber que "for-loops" eram uma coisa. Ele gosta de trabalhar com tecnologia que os desenvolvedores adoram, o que naturalmente o atraiu para o React. Fora do trabalho, ele gosta de ler, praticar kitesurf e tocar violão. </TeamMember> +<<<<<<< HEAD <TeamMember name="Josh Story" permalink="josh-story" photo="/images/team/josh.jpg" github="gnoff" bsky="storyhb.com" title="Engineer at Vercel"> Josh se formou em matemática e descobriu a programação na faculdade. Seu primeiro emprego profissional como desenvolvedor foi programar cálculos de taxas de seguro no Microsoft Excel, o padrão de Programação Reativa, que deve ser o motivo pelo qual ele agora trabalha com React. Nesse meio tempo, Josh foi um IC, gerente e executivo em algumas startups. Fora do trabalho, ele gosta de ir aos limites com a culinária. </TeamMember> @@ -66,10 +182,13 @@ Os membros atuais da equipe React estão listados em ordem alfabética abaixo. Mofei começou a programar quando percebeu que isso poderia ajudá-la a trapacear em videogames. Ela se concentrou em sistemas operacionais na graduação / pós-graduação, mas agora se vê feliz em trabalhar no React. Fora do trabalho, ela gosta de depurar problemas de boulder e planejar sua próxima viagem de mochila(s). </TeamMember> +======= +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca <TeamMember name="Pieter Vanderwerff" permalink="pieter-vanderwerff" photo="/images/team/pieter.jpg" github="pieterv" threads="pietervanderwerff" title="Engineer at Meta"> Pieter estudou ciência da construção, mas depois de não conseguir um emprego, ele fez um site e as coisas escalaram a partir daí. Na Meta, ele gosta de trabalhar com desempenho, linguagens e agora React. Quando ele não está programando, você pode encontrá-lo fora da estrada nas montanhas. </TeamMember> +<<<<<<< HEAD <TeamMember name="Rick Hanlon" permalink="rick-hanlonii" photo="/images/team/rickhanlonii.jpg" github="rickhanlonii" twitter="rickhanlonii" threads="rickhanlonii" bsky="ricky.fm" title="Engineer at Meta"> Ricky se formou em matemática teórica e de alguma forma se encontrou na equipe React Native por alguns anos antes de ingressar na equipe React. Quando ele não está programando, você pode encontrá-lo praticando snowboard, ciclismo, escalada, golfe ou fechando problemas do GitHub que não correspondem ao modelo do problema. </TeamMember> @@ -78,10 +197,13 @@ Os membros atuais da equipe React estão listados em ordem alfabética abaixo. A introdução de Ruslan à programação de UI começou quando ele era criança, editando manualmente modelos HTML para seus fóruns de jogos personalizados. De alguma forma, ele acabou se formando em Ciência da Computação. Ele gosta de música, jogos e memes. Principalmente memes. </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 se formou em psicologia. Ele geralmente é quieto. Mesmo quando ele diz algo, muitas vezes não faz sentido para o resto de nós até alguns meses depois. A maneira correta de pronunciar seu sobrenome é "mark-boa-geh", mas ele se contentou com "mark-beige" por pragmatismo - e é assim que ele aborda o 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 aprendeu programação para tornar os jogos de navegador que ele jogava durante a aula mais agradáveis. Eventualmente, isso o levou a contribuir com o máximo de código de código aberto possível. Fora da codificação, ele está ocupado garantindo que as pessoas não o confundam com os outros Sebastians e Zilberman da comunidade React. </TeamMember> @@ -94,10 +216,16 @@ Os membros atuais da equipe React estão listados em ordem alfabética abaixo. Quatro dias depois que o React foi lançado, Sophie reescreveu a totalidade de seu projeto atual para usá-lo, o que ela agora percebe que foi talvez um pouco imprudente. Depois que ela se tornou a committer nº 1 do projeto, ela se perguntou por que não estava sendo paga pelo Facebook como todos os outros e ingressou oficialmente na equipe para liderar o React em seus anos de adolescência. Embora ela tenha saído desse emprego anos atrás, de alguma forma ela ainda está nos chats em grupo da equipe e “fornecendo valor”. </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 estudou Ciência da Computação na escola. Ela gostava da gratificação instantânea de ver o código ganhar vida sem ter que estar fisicamente em um laboratório. Agora ela é gerente na organização React. Antes da gestão, ela costumava trabalhar no framework de busca de dados do Relay. Em seu tempo livre, Yuzhi gosta de otimizar sua vida por meio de jardinagem e projetos de melhoria da casa. </TeamMember> +<<<<<<< HEAD ## Contribuintes anteriores {/*past-contributors*/} -Você pode encontrar os membros da equipe anteriores e outras pessoas que contribuíram significativamente para o React ao longo dos anos na página de [agradecimentos](/community/acknowledgements). \ No newline at end of file +Você pode encontrar os membros da equipe anteriores e outras pessoas que contribuíram significativamente para o React ao longo dos anos na página de [agradecimentos](/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 04cc626af0..5f997a9b55 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -131,12 +131,21 @@ Se você é o autor de um framework, biblioteca, ferramenta de desenvolvedor ou Ou yarn: +<<<<<<< HEAD ```console yarn upgrade react@canary react-dom@canary ``` * Execute sua suíte de testes em relação aos pacotes atualizados. * Se tudo passar, ótimo! Você pode esperar que seu projeto funcione com o próximo lançamento secundário do React. * Se algo quebrar inesperadamente, avise-nos [abrindo uma issue](https://github.com/facebook/react/issues). +======= + ```console + yarn upgrade react@canary react-dom@canary + ``` +- 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 Um projeto que usa este fluxo de trabalho é o Next.js. Você pode consultar sua [configuração do CircleCI](https://github.com/zeit/next.js/blob/c0a1c0f93966fe33edd93fb53e5fafb0dcd80a9e/.circleci/config.yml) como exemplo. @@ -166,4 +175,8 @@ Se um recurso não estiver documentado, eles podem ser acompanhados por um [RFC] Postaremos no [blog do React](/blog) quando estivermos prontos para anunciar novos experimentos, mas isso não significa que divulgaremos todos os experimentos. -Você sempre pode consultar o [histórico](https://github.com/facebook/react/commits/main) do nosso repositório público do GitHub para obter uma lista abrangente de alterações. \ No newline at end of file +<<<<<<< HEAD +Você sempre pode consultar o [histórico](https://github.com/facebook/react/commits/main) do nosso repositório público do GitHub para obter uma lista abrangente de alterações. +======= +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 6564d6afb7..29e6a91bc3 100644 --- a/src/content/learn/react-compiler/debugging.md +++ b/src/content/learn/react-compiler/debugging.md @@ -43,10 +43,17 @@ Siga estes passos quando encontrar problemas: ### Erros de Compilação do Compilador {/*compiler-build-errors*/} +<<<<<<< HEAD Se você encontrar um erro do compilador que quebra inesperadamente sua compilação, isso provavelmente é um bug no compilador. Reporte-o para o repositório [facebook/react](https://github.com/facebook/react/issues) com: - A mensagem de erro - O código que causou o erro - Suas versões do React e do compilador +======= +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 ### Problemas em Tempo de Execução {/*runtime-issues*/} @@ -78,6 +85,7 @@ Você também pode tentar remover a memoização manual (useMemo, useCallback, m Se você acredita que encontrou um bug do compilador: +<<<<<<< HEAD 1. **Verifique se não é uma violação das Regras do React** - Verifique com o ESLint 2. **Crie uma reprodução mínima** - Isole o problema em um exemplo pequeno 3. **Teste sem o compilador** - Confirme que o problema só ocorre com a compilação @@ -86,6 +94,16 @@ Se você acredita que encontrou um bug do compilador: - Código de reprodução mínima - Comportamento esperado vs atual - Qualquer mensagem de erro +======= +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 ## Próximos Passos {/*next-steps*/} diff --git a/src/content/learn/react-compiler/installation.md b/src/content/learn/react-compiler/installation.md index d8b56b1e3c..37a33a5bf1 100644 --- a/src/content/learn/react-compiler/installation.md +++ b/src/content/learn/react-compiler/installation.md @@ -189,7 +189,11 @@ Instale o plugin ESLint: npm install -D eslint-plugin-react-hooks@latest </TerminalBlock> +<<<<<<< HEAD Se você ainda não configurou o eslint-plugin-react-hooks, siga as [instruções de instalação no readme](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation). As regras do compilador estão disponíveis no preset `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 A regra ESLint irá: - Identificar violações das [Regras do React](/reference/rules) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index aeb9f50d89..d406e911c6 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -899,6 +899,7 @@ body { ### Ferramentas do Desenvolvedor React {/*react-developer-tools*/} +<<<<<<< HEAD As DevTools do React permitem que você cheque as *props* e o *state* de seus componentes React. Você pode encontrar a aba de DevTools do React na parte inferior da seção *navegador* no CodeSandbox: ![React DevTools no CodeSandbox](../images/tutorial/codesandbox-devtools.png) @@ -906,12 +907,26 @@ As DevTools do React permitem que você cheque as *props* e o *state* de seus co Para inspecionar um componente em particular na tela, use o botão no canto superior esquerdo das DevTools do React: ![Selecionando componente na página com as DevTools do React](../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 Para desenvolvimento local, as DevTools do React estão disponíveis como extensões de navegador para [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en), [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/), e [Edge](https://microsoftedge.microsoft.com/addons/detail/react-developer-tools/gpphkfbcpidddadnkolkpfckpihlkkil). Instale-as, e a aba *Components* irá aparecer nas ferramentas de desenvolvedor do seu navegador para sites utilizando React. +======= +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> ## Completando o jogo {/*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 55c98268d7..55765aac58 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,11 @@ Essas bibliotecas foram projetadas antes que as regras de memoização do React ## Detalhes da Regra {/*rule-details*/} +<<<<<<< HEAD Algumas bibliotecas usam padrões que não são suportados pelo React. Quando o linter detecta usos dessas APIs de uma [lista conhecida](https://github.com/facebook/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/HIR/DefaultModuleTypeProvider.ts), ele as sinaliza sob esta regra. Isso significa que o Compilador React pode pular automaticamente componentes que usam essas APIs incompatíveis, a fim de evitar a quebra do seu aplicativo. +======= +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. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca ```js // Exemplo de como a memoização quebra com essas bibliotecas @@ -135,4 +139,8 @@ function Component() { } ``` -Algumas outras bibliotecas ainda não possuem APIs alternativas que sejam compatíveis com o modelo de memoização do React. Se o linter não pular automaticamente seus componentes ou hooks que chamam essas APIs, por favor, [abra uma issue](https://github.com/facebook/react/issues) para que possamos adicioná-la ao linter. \ No newline at end of file +<<<<<<< HEAD +Algumas outras bibliotecas ainda não possuem APIs alternativas que sejam compatíveis com o modelo de memoização do React. Se o linter não pular automaticamente seus componentes ou hooks que chamam essas APIs, por favor, [abra uma issue](https://github.com/facebook/react/issues) para que possamos adicioná-la ao 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. +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index 64891be686..fc06ad00bf 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -36,7 +36,11 @@ Estas props especiais do React são suportadas para todos os componentes nativos * `suppressHydrationWarning`: Um booleano. Se você usar [renderização no servidor,](/reference/react-dom/server) normalmente há um aviso quando o servidor e o cliente renderizam conteúdo diferente. Em alguns casos raros (como timestamps), é muito difícil ou impossível garantir uma correspondência exata. Se você definir `suppressHydrationWarning` como `true`, o React não o avisará sobre incompatibilidades nos atributos e no conteúdo desse elemento. Ele só funciona em um nível de profundidade e é projetado para ser usado como uma porta de saída. Não use em excesso. [Leia sobre como suprimir erros de hidratação.](/reference/react-dom/client/hydrateRoot#suppressing-unavoidable-hydration-mismatch-errors) +<<<<<<< HEAD * `style`: Um objeto com estilos CSS, por exemplo, `{ fontWeight: 'bold', margin: 20 }`. Semelhante à propriedade [`style`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style), os nomes das propriedades CSS precisam ser escritos como `camelCase`, por exemplo, `fontWeight` em vez de `font-weight`. Você pode passar strings ou números como valores. Se você passar um número, como `width: 100`, o React anexará automaticamente `px` ("pixels") ao valor, a menos que seja uma [propriedade sem unidade.](https://github.com/facebook/react/blob/81d4ee9ca5c405dce62f64e61506b8e155f38d8d/packages/react-dom-bindings/src/shared/CSSProperty.js#L8-L57) Recomendamos que você use `style` apenas para estilos dinâmicos nos quais você não conhece os valores do estilo com antecedência. Em outros casos, aplicar classes CSS simples com `className` é mais eficiente. [Leia mais sobre `className` e `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 Essas props DOM padrão também são suportadas para todos os componentes nativos: diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 655aaa5ab4..536adffce1 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -48,9 +48,53 @@ Para criar controles interativos para enviar informações, renderize o [compone ## Uso {/*usage*/} +<<<<<<< HEAD ### Manipular envio de formulário no cliente {/*handle-form-submission-on-the-client*/} Passe uma função para a prop `action` do formulário para executar a função quando o formulário for enviado. [`formData`](https://developer.mozilla.org/pt-BR/docs/Web/API/FormData) será passado para a função como um argumento para que você possa acessar os dados enviados pelo formulário. Isso difere da [ação HTML](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/form#action) convencional, que aceita apenas URLs. Após a execução da função `action`, todos os elementos de campo não controlados no formulário são redefinidos. +======= +### 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 04c9fe9320..a2c75347cb 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -48,6 +48,7 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * `reactNode`: Um nó React que você deseja renderizar em HTML. Por exemplo, um elemento JSX como `<App />`. Espera-se que ele represente o documento inteiro, então o componente `App` deve renderizar a tag `<html>`. +<<<<<<< HEAD * **opcional** `options`: Um objeto com opções de streaming. * **opcional** `bootstrapScriptContent`: Se especificado, esta string será colocada em uma tag `<script>` inline. * **opcional** `bootstrapScripts`: Uma matriz de URLs de string para as tags `<script>` a serem emitidas na página. Use isso para incluir o `<script>` que chama [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omita-o se você não quiser executar o React no cliente. @@ -60,6 +61,20 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * **opcional** `onShellReady`: Um callback que é acionado logo após o [shell inicial](#specifying-what-goes-into-the-shell) ser renderizado. Você pode [definir o código de status](#setting-the-status-code) e chamar `pipe` aqui para iniciar o streaming. O React [fará o streaming do conteúdo adicional](#streaming-more-content-as-it-loads) após o shell, juntamente com as tags `<script>` inline que substituem os fallbacks de carregamento HTML com o conteúdo. * **opcional** `onShellError`: Um callback que é acionado se houver um erro ao renderizar o shell inicial. Ele recebe o erro como um argumento. Nenhum byte foi emitido do stream ainda, e nem `onShellReady` nem `onAllReady` serão chamados, para que você possa [gerar um fallback shell HTML.](#recovering-from-errors-inside-the-shell) * **opcional** `progressiveChunkSize`: O número de bytes em um chunk. [Leia mais sobre a heurística padrão.](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 #### Retorna {/*returns*/} @@ -284,6 +299,7 @@ O streaming não precisa esperar que o próprio React carregue no navegador ou q <Note> +<<<<<<< HEAD **Apenas fontes de dados ativadas pelo Suspense ativarão o componente Suspense.** Eles incluem: - Busca de dados com frameworks com suporte ao Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/getting-started/react-essentials) @@ -295,6 +311,9 @@ Suspense **não** detecta quando os dados são buscados dentro de um Effect ou m A maneira exata como você carregaria dados no componente `Posts` acima depende do seu framework. Se você usar um framework com suporte ao Suspense, encontrará os detalhes em sua documentação de busca de dados. A busca de dados habilitada para Suspense sem o uso de um framework opinativo ainda não é compatível. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não estão documentados. Uma API oficial para integrar fontes de dados ao Suspense será lançada em uma versão futura do 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 cda4ad562c..60ea4d59ed 100644 --- a/src/content/reference/react-dom/server/renderToReadableStream.md +++ b/src/content/reference/react-dom/server/renderToReadableStream.md @@ -49,6 +49,7 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * `reactNode`: Um nó React que você deseja renderizar para HTML. Por exemplo, um elemento JSX como `<App />`. Espera-se que ele represente o documento inteiro, então o componente `App` deve renderizar a tag `<html>`. +<<<<<<< HEAD * **opcional** `options`: Um objeto com opções de streaming. * **opcional** `bootstrapScriptContent`: Se especificado, esta string será colocada em uma tag `<script>` inline. * **opcional** `bootstrapScripts`: Uma array de URLs de string para as tags `<script>` a serem emitidas na página. Use isso para incluir o `<script>` que chama [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omita se você não quiser executar React no cliente. @@ -59,6 +60,18 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * **opcional** `onError`: Um callback que é acionado sempre que houver um erro de servidor, seja [recuperável](#recovering-from-errors-outside-the-shell) ou [não.](#recovering-from-errors-inside-the-shell) Por padrão, isso só chama `console.error`. Se você substituí-lo para [registrar relatórios de falhas,](#logging-crashes-on-the-server) certifique-se de ainda chamar `console.error`. Você também pode usá-lo para [ajustar o código de status](#setting-the-status-code) antes que o shell seja emitido. * **opcional** `progressiveChunkSize`: O número de bytes em um chunk. [Leia mais sobre a heurística padrão.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) * **opcional** `signal`: Um [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) que permite [abortar a renderização do servidor](#aborting-server-rendering) e renderizar o restante no cliente. +======= +* **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 #### Retorna {/*returns*/} @@ -281,6 +294,7 @@ O streaming não precisa esperar que o próprio React carregue no navegador ou q <Note> +<<<<<<< HEAD **Somente fontes de dados habilitadas para Suspense ativarão o componente Suspense.** Eles incluem: - Recuperação de dados com frameworks habilitados para Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/getting-started/react-essentials) @@ -292,6 +306,9 @@ Suspense **não** detecta quando os dados são buscados dentro de um Effect ou m A maneira exata como você carregaria os dados no componente `Posts` acima depende do seu framework. Se você usar um framework habilitado para Suspense, encontrará os detalhes em sua documentação de busca de dados. A busca de dados habilitada para Suspense sem o uso de um framework opinativo ainda não é suportada. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não documentados. Uma API oficial para integrar fontes de dados com Suspense será lançada em uma versão futura do 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 2aee89faf5..bfddf5b40b 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -49,6 +49,7 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * `reactNode`: Um nó React que você quer renderizar em HTML. Por exemplo, um nó JSX como `<App />`. Espera-se que ele represente o documento inteiro, então o componente App deve renderizar a tag `<html>`. +<<<<<<< HEAD * **opcional** `options`: Um objeto com opções de geração estática. * **opcional** `bootstrapScriptContent`: Se especificado, esta string será colocada em uma tag `<script>` inline. * **opcional** `bootstrapScripts`: Uma array de URLs de string para as tags `<script>` a serem emitidas na página. Use isso para incluir o `<script>` que chama [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omita-o se você não quiser executar o React no cliente. @@ -58,6 +59,17 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * **opcional** `onError`: Um retorno de chamada que é disparado sempre que há um erro de servidor, seja ele [recuperável](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-outside-the-shell) ou [não.](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell) Por padrão, isso chama apenas `console.error`. Se você substituí-lo para [registrar relatórios de falhas,](/reference/react-dom/server/renderToReadableStream#logging-crashes-on-the-server) certifique-se de ainda chamar `console.error`. Você também pode usá-lo para [ajustar o código de status](/reference/react-dom/server/renderToReadableStream#setting-the-status-code) antes da emissão do shell. * **opcional** `progressiveChunkSize`: O número de bytes em um bloco. [Saiba mais sobre a heurística padrão.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) * **opcional** `signal`: Um [sinal de aborto](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) que permite [abortar a pré-renderização](#aborting-prerendering) e renderizar o restante no cliente. +======= +* **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 #### Retorna {/*returns*/} @@ -276,6 +288,7 @@ Imagine que `<Posts />` precisa carregar alguns dados, o que leva algum tempo. I <Note> +<<<<<<< HEAD **Somente fontes de dados habilitadas para Suspense ativarão o componente Suspense.** Elas incluem: - Busca de dados com frameworks habilitados para Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/getting-started/react-essentials) @@ -287,6 +300,9 @@ Suspense **não** detecta quando os dados são buscados dentro de um Effect ou m A maneira exata de como você carregaria dados no componente `Posts` acima depende do seu framework. Se você usa um framework habilitado para Suspense, você encontrará os detalhes na documentação de busca de dados dele. A busca de dados habilitada para Suspense sem o uso de um framework que dê opiniões ainda não é suportada. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não documentados. Uma API oficial para integrar fontes de dados com Suspense será lançada em uma versão futura do 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 ac979423b4..a75d576754 100644 --- a/src/content/reference/react-dom/static/prerenderToNodeStream.md +++ b/src/content/reference/react-dom/static/prerenderToNodeStream.md @@ -50,6 +50,7 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * `reactNode`: Um nó React que você quer renderizar em HTML. Por exemplo, um nó JSX como `<App />`. Espera-se que ele represente o documento inteiro, então o componente App deve renderizar a tag `<html>`. +<<<<<<< HEAD * **opcional** `options`: Um objeto com opções de geração estática. * **opcional** `bootstrapScriptContent`: Se especificado, esta string será colocada em uma tag `<script>` embutida. * **opcional** `bootstrapScripts`: Uma array de URLs de strings para as tags `<script>` a serem emitidas na página. Use isso para incluir o `<script>` que chama [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omita-o se você não quiser executar React no cliente de forma alguma. @@ -59,6 +60,17 @@ No cliente, chame [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) para * **opcional** `onError`: Um retorno de chamada que é disparado sempre que há um erro de servidor, seja ele [recuperável](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-outside-the-shell) ou [não.](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-inside-the-shell). Por padrão, isso chama apenas `console.error`. Se você substituí-lo para [registrar relatórios de falhas,](/reference/react-dom/server/renderToPipeableStream#logging-crashes-on-the-server), certifique-se de ainda chamar `console.error`. Você também pode usá-lo para [ajustar o código de status](/reference/react-dom/server/renderToPipeableStream#setting-the-status-code) antes da emissão do shell. * **opcional** `progressiveChunkSize`: O número de bytes em um bloco. [Saiba mais sobre a heurística padrão.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) * **opcional** `signal`: Um [sinal de aborto](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) que permite [abortar a pré-renderização](#aborting-prerendering) e renderizar o restante no cliente. +======= +* **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 #### Retorna {/*returns*/} @@ -276,6 +288,7 @@ Imagine que `<Posts />` precisa carregar alguns dados, o que leva algum tempo. I <Note> +<<<<<<< HEAD **Apenas fontes de dados habilitadas para Suspense ativarão o componente Suspense.** Elas incluem: - Busca de dados com frameworks habilitados para Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/getting-started/react-essentials) @@ -287,6 +300,9 @@ Suspense **não** detecta quando os dados são buscados dentro de um Effect ou m A maneira exata como você carregaria os dados no componente `Posts` acima depende de sua framework. Se você usa uma framework habilitada para Suspense, encontrará os detalhes em sua documentação de busca de dados. O data fetching habilitado para Suspense sem o uso de um framework opinativo ainda não é suportado. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não documentados. Uma API oficial para integrar fontes de dados com Suspense será lançada em uma versão futura do 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 d82f99b0ae..6df8bc9f45 100644 --- a/src/content/reference/react/Activity.md +++ b/src/content/reference/react/Activity.md @@ -755,6 +755,7 @@ A pré-renderização de componentes com limites de Activity ocultos é uma mane <Note> +<<<<<<< HEAD **Apenas fontes de dados habilitadas para Suspense serão buscadas durante a pré-renderização.** Elas incluem: - Busca de dados com frameworks habilitados para Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) @@ -766,6 +767,9 @@ Activity **não** detecta dados que são buscados dentro de um Effect. A maneira exata como você buscaria dados no componente `Posts` acima depende do seu framework. Se você usar um framework habilitado para Suspense, encontrará os detalhes em sua documentação de busca de dados. A busca de dados habilitada para Suspense sem o uso de um framework opinativo ainda não é suportada. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não documentados. Uma API oficial para integrar fontes de dados com Suspense será lançada em uma versão futura do 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 f1f8facbec..4fc84c5509 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -1007,7 +1007,11 @@ Derivar o estado leva a um código prolixo e dificulta a reflexão sobre seus co #### Ressalvas {/*static-getderivedstatefromprops-caveats*/} +<<<<<<< HEAD - Este método é disparado em *cada* renderização, independentemente da causa. Isso é diferente de [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops), que só é disparado quando os pais causam uma nova renderização e não como resultado de um `setState` local. +======= +- 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 - Este método não tem acesso à instância do componente. Se você quiser, poderá reutilizar algum código entre `static getDerivedStateFromProps` e os outros métodos de classe, extraindo funções puras das props e do estado do componente fora da definição da classe. diff --git a/src/content/reference/react/Fragment.md b/src/content/reference/react/Fragment.md index 1e7553bfb3..cea6e139da 100644 --- a/src/content/reference/react/Fragment.md +++ b/src/content/reference/react/Fragment.md @@ -6,7 +6,7 @@ title: <Fragment> (<>...</>) `<Fragment>`, frequentemente usado por meio da sintaxe `<>...</>`, permite agrupar elementos sem um nó de encapsulamento. -<Canary> Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements. See reference and usage below.</Canary> +<Canary>Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements.</Canary> ```js <> @@ -29,6 +29,7 @@ Encapsule elementos em `<Fragment>` para agrupá-los juntos em situações em qu #### Props {/*props*/} +<<<<<<< HEAD - **opcional** `key`: Fragments declarados com a sintaxe explícita `<Fragment>` podem ter [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key) - <CanaryBadge /> **opcional** `ref`: Um objeto ref (por exemplo, de [`useRef`](/reference/react/useRef)) ou uma [função de callback](/reference/react-dom/components/common#ref-callback). O React fornece um `FragmentInstance` como valor da ref que implementa métodos para interagir com os nós DOM encapsulados pelo Fragment. @@ -57,14 +58,267 @@ Quando você passa uma ref para um fragment, o React fornece um objeto `Fragment **Métodos de observação:** - `observeUsing(observer)`: Inicia a observação dos filhos DOM do Fragment com um IntersectionObserver ou ResizeObserver. - `unobserveUsing(observer)`: Para a observação dos filhos DOM do Fragment com o observador especificado. +======= +- **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 #### Cuidados {/*caveats*/} +<<<<<<< HEAD - Se você quiser passar uma `key` para um Fragment, não pode usar a sintaxe `<>...</>`. Você precisa importar explicitamente o `Fragment` de `'react'` e renderizar `<Fragment key={suaChave}>...</Fragment>`. - O React não [reseta o estado](/learn/preserving-and-resetting-state) quando você passa de `<><Child /></>` para `[<Child />]` ou vice-versa, ou quando você passa de `<><Child /></>` para `<Child />` e vice-versa. Isso funciona apenas para um único nível: por exemplo, passar de `<><><Child /></></>` para `<Child />` reseta o estado. Veja a semântica precisa [aqui.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b). +======= +* 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>`. -- <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>`. +* 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) +>>>>>>> 6be2b020a0cabf2fd6dbff5c42c399b8ac323bca + +* <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. --- @@ -242,47 +496,312 @@ function PostBody({ body }) { --- -### <CanaryBadge /> Using Fragment refs for DOM interaction {/*using-fragment-refs-for-dom-interaction*/} +### <CanaryBadge /> Adding event listeners without a wrapper element {/*adding-event-listeners-without-wrapper*/} -Fragment refs allow you to interact with the DOM nodes wrapped by a Fragment without adding extra wrapper elements. This is useful for event handling, visibility tracking, focus management, and replacing deprecated patterns like `ReactDOM.findDOMNode()`. +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> ```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> + +--- + +### <CanaryBadge /> Managing focus across a group of elements {/*managing-focus-across-elements*/} + +Fragment `ref`s provide `focus`, `focusLast`, and `blur` methods that operate across all DOM nodes within the Fragment: + +<Sandpack> + +```js +import { Fragment, useRef } from 'react'; + +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 /> Tracking visibility with Fragment refs {/*tracking-visibility-with-fragment-refs*/} +### <CanaryBadge /> Observing visibility without a wrapper element {/*observing-visibility-without-wrapper*/} -Fragment refs are useful for visibility tracking and intersection observation. This enables you to monitor when content becomes visible without requiring the child Components to expose refs: +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: -```js {19,21,31-34} -import { Fragment, useRef, useLayoutEffect } from 'react'; +<Sandpack> -function VisibilityObserverFragment({ threshold = 0.5, onVisibilityChange, children }) { +```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,38 +810,258 @@ 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> ); } ``` -This pattern is an alternative to Effect-based visibility logging, which is an anti-pattern in most cases. Relying on Effects alone does not guarantee that the rendered Component is observable by the user. +```css +.page { + transition: background 0.3s; +} + +.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 /> Focus management with Fragment refs {/*focus-management-with-fragment-refs*/} +### <CanaryBadge /> Caching a global IntersectionObserver {/*caching-global-intersection-observer*/} -Fragment refs provide focus management methods that work across all DOM nodes within the Fragment: +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. -```js -import { Fragment, useRef } from 'react'; +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> ); } ``` -The `focus()` method focuses the first focusable element within the Fragment, while `focusLast()` focuses the last focusable element. +```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. diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 03d4244133..08acb12f07 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -23,11 +23,18 @@ title: <Suspense> ### `<Suspense>` {/*suspense*/} #### Props {/*props*/} +<<<<<<< HEAD * `children`: A UI real que você pretende renderizar. Se `children` suspender durante a renderização, o limite do Suspense mudará para renderizar `fallback`. * `fallback`: Uma UI alternativa para renderizar no lugar da UI real se ela não tiver terminado de carregar. Qualquer nó React válido é aceito, embora na prática, um fallback seja uma visualização de espaço reservado leve, como um indicador de carregamento ou esqueleto. Suspense mudará automaticamente para `fallback` quando `children` suspender, e de volta para `children` quando os dados estiverem prontos. Se `fallback` suspender durante a renderização, ele ativará o limite do Suspense pai mais próximo. +======= +* `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 #### Ressalvas {/*caveats*/} +<<<<<<< HEAD - React não preserva nenhum estado para renderizações que foram suspensas antes de poderem montar pela primeira vez. Quando o componente tiver carregado, React tentará renderizar a árvore suspensa do zero. - Se Suspense estava exibindo conteúdo para a árvore, mas então suspendeu novamente, o `fallback` será mostrado novamente, a menos que a atualização que o causou tenha sido causada por [`startTransition`](/reference/react/startTransition) ou [`useDeferredValue`](/reference/react/useDeferredValue). - Se React precisar ocultar o conteúdo já visível porque ele suspendeu novamente, ele limpará os [Effects de layout](/reference/react/useLayoutEffect) na árvore de conteúdo. Quando o conteúdo estiver pronto para ser mostrado novamente, React executará os Effects de layout novamente. Isso garante que os Effects que medem o layout do DOM não tentem fazer isso enquanto o conteúdo estiver oculto. @@ -36,6 +43,42 @@ title: <Suspense> --- ## Uso {/*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 ### Exibindo um fallback enquanto o conteúdo está carregando {/*displaying-a-fallback-while-content-is-loading*/} @@ -202,8 +245,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 **Apenas fontes de dados habilitadas para Suspense ativarão o componente Suspense.** Elas incluem: - Busca de dados com frameworks habilitados para Suspense como [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) e [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) @@ -215,8 +259,256 @@ Suspense **não** detecta quando os dados são buscados dentro de um Effect ou m A maneira exata de carregar dados no componente `Albums` acima depende do seu framework. Se você usa um framework habilitado para Suspense, você encontrará os detalhes na documentação de busca de dados dele. A busca de dados habilitada para Suspense sem o uso de um framework com opinião ainda não é suportada. Os requisitos para implementar uma fonte de dados habilitada para Suspense são instáveis e não documentados. Uma API oficial para integrar fontes de dados com Suspense será lançada em uma versão futura do 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(); +} +``` + + --- @@ -1990,15 +2282,108 @@ main { ### Resetando limites de Suspense na navegação {/*resetting-suspense-boundaries-on-navigation*/} +<<<<<<< HEAD Durante uma Transition, o React evitará ocultar o conteúdo já revelado. No entanto, se você navegar para uma rota com parâmetros diferentes, você pode querer dizer ao React que é um conteúdo *diferente*. Você pode expressar isso com uma `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 Imagine que você está navegando dentro da página de perfil de um usuário e algo suspende. Se essa atualização estiver envolvida em uma Transition, ela não acionará o fallback para o conteúdo já visível. Esse é o comportamento esperado. No entanto, agora imagine que você está navegando entre dois perfis de usuário diferentes. Nesse caso, faz sentido mostrar o fallback. Por exemplo, a linha do tempo de um usuário é um *conteúdo diferente* da linha do tempo de outro usuário. Especificando uma `key`, você garante que o React trate os perfis de usuários diferentes como componentes diferentes e redefine os limites de Suspense durante a navegação. Roteadores integrados ao Suspense devem fazer isso automaticamente. +======= +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 --- @@ -2027,7 +2412,876 @@ O HTML do servidor incluirá o indicador de carregamento. Ele será substituído --- +<<<<<<< HEAD ## Solução de problemas {/*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 ( + <> + +