diff --git a/public/images/tutorial/react-starter-code-codesandbox.png b/public/images/tutorial/react-starter-code-codesandbox.png old mode 100644 new mode 100755 index d65f161bc..b01e18297 Binary files a/public/images/tutorial/react-starter-code-codesandbox.png and b/public/images/tutorial/react-starter-code-codesandbox.png differ diff --git a/src/components/DocsFooter.tsx b/src/components/DocsFooter.tsx index 5f2330e7e..93c2ca125 100644 --- a/src/components/DocsFooter.tsx +++ b/src/components/DocsFooter.tsx @@ -80,7 +80,7 @@ function FooterLink({ />
- {type} + {type === 'Previous' ? 'Previous' : 'Next'} {title} diff --git a/src/components/Icon/IconArrowSmall.tsx b/src/components/Icon/IconArrowSmall.tsx index 4a3d3ad02..a70717c9d 100644 --- a/src/components/Icon/IconArrowSmall.tsx +++ b/src/components/Icon/IconArrowSmall.tsx @@ -19,6 +19,7 @@ export const IconArrowSmall = memo< const classes = cn(className, { 'rotate-180': displayDirection === 'left', 'rotate-180 rtl:rotate-0': displayDirection === 'start', + 'rtl:rotate-180': displayDirection === 'end', 'rotate-90': displayDirection === 'down', }); return ( diff --git a/src/components/Icon/IconExperimental.tsx b/src/components/Icon/IconExperimental.tsx index 0bba612eb..c0f69e3f9 100644 --- a/src/components/Icon/IconExperimental.tsx +++ b/src/components/Icon/IconExperimental.tsx @@ -6,7 +6,7 @@ import {memo} from 'react'; export const IconExperimental = memo< JSX.IntrinsicElements['svg'] & {title?: string; size?: 's' | 'md'} ->(function IconCanary( +>(function IconExperimental( {className, title, size} = { className: undefined, title: undefined, diff --git a/src/components/MDX/Challenges/Navigation.tsx b/src/components/MDX/Challenges/Navigation.tsx index 736db093c..b4d8c0924 100644 --- a/src/components/MDX/Challenges/Navigation.tsx +++ b/src/components/MDX/Challenges/Navigation.tsx @@ -108,7 +108,7 @@ export function Navigation({ onClick={handleScrollLeft} aria-label="Scroll left" className={cn( - 'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-l border-gray-20 border-r rtl:rotate-180', + 'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-l rtl:rounded-r rtl:rounded-l-none border-gray-20 border-r rtl:border-l rtl:border-r-0', { 'text-primary dark:text-primary-dark': canScrollLeft, 'text-gray-30': !canScrollLeft, @@ -120,7 +120,7 @@ export function Navigation({ onClick={handleScrollRight} aria-label="Scroll right" className={cn( - 'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-e rtl:rotate-180', + 'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-e', { 'text-primary dark:text-primary-dark': canScrollRight, 'text-gray-30': !canScrollRight, diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index fede45bb4..bfbe26604 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -37,6 +37,7 @@ import {finishedTranslations} from 'utils/finishedTranslations'; import ErrorDecoder from './ErrorDecoder'; import {IconCanary} from '../Icon/IconCanary'; +import {IconExperimental} from 'components/Icon/IconExperimental'; function CodeStep({children, step}: {children: any; step: number}) { return ( @@ -130,7 +131,7 @@ const ExperimentalBadge = ({title}: {title: string}) => ( 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' }> - diff --git a/src/components/MDX/Sandpack/ClearButton.tsx b/src/components/MDX/Sandpack/ClearButton.tsx new file mode 100644 index 000000000..868f9fb66 --- /dev/null +++ b/src/components/MDX/Sandpack/ClearButton.tsx @@ -0,0 +1,22 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + */ + +import * as React from 'react'; +import {IconClose} from '../../Icon/IconClose'; +export interface ClearButtonProps { + onClear: () => void; +} + +export function ClearButton({onClear}: ClearButtonProps) { + return ( + + ); +} diff --git a/src/components/MDX/Sandpack/NavigationBar.tsx b/src/components/MDX/Sandpack/NavigationBar.tsx index bf2c3186c..d115868dd 100644 --- a/src/components/MDX/Sandpack/NavigationBar.tsx +++ b/src/components/MDX/Sandpack/NavigationBar.tsx @@ -17,7 +17,8 @@ import { useSandpackNavigation, } from '@codesandbox/sandpack-react/unstyled'; import {OpenInCodeSandboxButton} from './OpenInCodeSandboxButton'; -import {ResetButton} from './ResetButton'; +import {ReloadButton} from './ReloadButton'; +import {ClearButton} from './ClearButton'; import {DownloadButton} from './DownloadButton'; import {IconChevron} from '../../Icon/IconChevron'; import {Listbox} from '@headlessui/react'; @@ -95,7 +96,7 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) { // Note: in a real useEvent, onContainerResize would be omitted. }, [isMultiFile, onContainerResize]); - const handleReset = () => { + const handleClear = () => { /** * resetAllFiles must come first, otherwise * the previous content will appear for a second @@ -103,13 +104,13 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) { * * Plus, it should only prompt if there's any file changes */ - if ( - sandpack.editorState === 'dirty' && - confirm('Reset all your edits too?') - ) { + if (sandpack.editorState === 'dirty' && confirm('Clear all your edits?')) { sandpack.resetAllFiles(); } + refresh(); + }; + const handleReload = () => { refresh(); }; @@ -188,7 +189,8 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) { className="px-3 flex items-center justify-end text-start" translate="yes"> - + + {activeFile.endsWith('.tsx') && ( void; +export interface ReloadButtonProps { + onReload: () => void; } -export function ResetButton({onReset}: ResetButtonProps) { +export function ReloadButton({onReload}: ReloadButtonProps) { return ( ); } diff --git a/src/content/blog/2025/04/21/react-compiler-rc.md b/src/content/blog/2025/04/21/react-compiler-rc.md index ecbbb8747..2ebbf3bae 100644 --- a/src/content/blog/2025/04/21/react-compiler-rc.md +++ b/src/content/blog/2025/04/21/react-compiler-rc.md @@ -57,23 +57,23 @@ During the RC period, we encourage all React users to try the compiler and provi As noted in the Beta announcement, React Compiler is compatible with React 17 and up. If you are not yet on React 19, you can use React Compiler by specifying a minimum target in your compiler config, and adding `react-compiler-runtime` as a dependency. You can find docs on this [here](https://react.dev/learn/react-compiler#using-react-compiler-with-react-17-or-18). ## Migrating from eslint-plugin-react-compiler to eslint-plugin-react-hooks {/*migrating-from-eslint-plugin-react-compiler-to-eslint-plugin-react-hooks*/} -If you have already installed eslint-plugin-react-compiler, you can now remove it and use `eslint-plugin-react-hooks@6.0.0-rc.1`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement! +If you have already installed eslint-plugin-react-compiler, you can now remove it and use `eslint-plugin-react-hooks@rc`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement! To install: npm -{`npm install --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`} +{`npm install --save-dev eslint-plugin-react-hooks@rc`} pnpm -{`pnpm add --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`} +{`pnpm add --save-dev eslint-plugin-react-hooks@rc`} yarn -{`yarn add --dev eslint-plugin-react-hooks@6.0.0-rc.1`} +{`yarn add --dev eslint-plugin-react-hooks@rc`} ```js 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 0f54d02b4..c7f740091 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 @@ -2521,7 +2521,7 @@ export default function App() { const { url } = useRouter(); // Define a default animation of .slow-fade. - // See animations.css for the animation definiton. + // See animations.css for the animation definition. return ( {url === '/' ? :
} @@ -11465,6 +11465,14 @@ _For more background on how we built View Transitions, see: [#31975](https://git ## Activity {/*activity*/} + + +**`` is now available in React’s Canary channel.** + +[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels) + + + In [past](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#offscreen) [updates](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024#offscreen-renamed-to-activity), we shared that we were researching an API to allow components to be visually hidden and deprioritized, preserving UI state with reduced performance costs relative to unmounting or hiding with CSS. We're now ready to share the API and how it works, so you can start testing it in experimental React versions. diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index a97f3d5b4..9354dc9c3 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -10,36 +10,6 @@ Do you know of a local React.js conference? Add it here! (Please keep the list c ## Upcoming Conferences {/*upcoming-conferences*/} -### CityJS London 2025 {/*cityjs-london*/} -April 23 - 25, 2025. In-person in London, UK - -[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) - -### App.js Conf 2025 {/*appjs-conf-2025*/} -May 28 - 30, 2025. In-person in Kraków, Poland + remote - -[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) - -### CityJS Athens 2025 {/*cityjs-athens*/} -May 27 - 31, 2025. In-person in Athens, Greece - -[Website](https://athens.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) - -### React Norway 2025 {/*react-norway-2025*/} -June 13, 2025. In-person in Oslo, Norway + remote (virtual event) - -[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway) - -### React Summit 2025 {/*react-summit-2025*/} -June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event) - -[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit) - -### React Nexus 2025 {/*react-nexus-2025*/} -July 03 - 05, 2025. In-person in Bangalore, India - -[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in) - ### React Universe Conf 2025 {/*react-universe-conf-2025*/} September 2-4, 2025. Wrocław, Poland. @@ -50,6 +20,11 @@ October 2-4, 2025. Alicante, Spain. [Website](https://reactalicante.es/) - [Twitter](https://x.com/ReactAlicante) - [Bluesky](https://bsky.app/profile/reactalicante.es) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w) +### RenderCon Kenya 2025 {/*rendercon-kenya-2025*/} +October 04, 2025. Nairobi, Kenya + +[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA) + ### React Conf 2025 {/*react-conf-2025*/} October 7-8, 2025. Henderson, Nevada, USA and free livestream @@ -60,6 +35,12 @@ October 31 - November 01, 2025. In-person in Goa, India (hybrid event) + Oct 15 [Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w) + +### CityJS New Delhi 2025 {/*cityjs-newdelhi*/} +November 6-7, 2025. In-person in New Delhi, India + +[Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) + ### React Summit US 2025 {/*react-summit-us-2025*/} November 18 - 21, 2025. In-person in New York, USA + remote (hybrid event) @@ -70,13 +51,49 @@ November 28 & December 1, 2025. In-person in London, UK + online (hybrid event) [Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced) +### React Paris 2026 {/*react-paris-2026*/} +March 26 - 27, 2026. In-person in Paris, France (hybrid event) + +[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_) + ## Past Conferences {/*past-conferences*/} + +### React Nexus 2025 {/*react-nexus-2025*/} +July 03 - 05, 2025. In-person in Bangalore, India + +[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in) + +### React Summit 2025 {/*react-summit-2025*/} +June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event) + +[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit) + +### React Norway 2025 {/*react-norway-2025*/} +June 13, 2025. In-person in Oslo, Norway + remote (virtual event) + +[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway) + +### CityJS Athens 2025 {/*cityjs-athens*/} +May 27 - 31, 2025. In-person in Athens, Greece + +[Website](https://athens.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) + +### App.js Conf 2025 {/*appjs-conf-2025*/} +May 28 - 30, 2025. In-person in Kraków, Poland + remote + +[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) + +### CityJS London 2025 {/*cityjs-london*/} +April 23 - 25, 2025. In-person in London, UK + +[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) + ### React Paris 2025 {/*react-paris-2025*/} March 20 - 21, 2025. In-person in Paris, France (hybrid event) -[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_) +[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_) - [YouTube](https://www.youtube.com/playlist?list=PL53Z0yyYnpWitP8Zv01TSEQmKLvuRh_Dj) ### React Native Connection 2025 {/*react-native-connection-2025*/} April 3 (Reanimated Training) + April 4 (Conference), 2025. Paris, France. diff --git a/src/content/community/meetups.md b/src/content/community/meetups.md index 479ae50d4..78d48093a 100644 --- a/src/content/community/meetups.md +++ b/src/content/community/meetups.md @@ -58,6 +58,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [Manchester](https://www.meetup.com/Manchester-React-User-Group/) * [React.JS Girls London](https://www.meetup.com/ReactJS-Girls-London/) * [React Advanced London](https://guild.host/react-advanced-london) +* [React Native Liverpool](https://www.meetup.com/react-native-liverpool/) * [React Native London](https://guild.host/RNLDN) ## Finland {/*finland*/} @@ -137,6 +138,9 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet ## Portugal {/*portugal*/} * [Lisbon](https://www.meetup.com/JavaScript-Lisbon/) +## Scotland (UK) {/*scotland-uk*/} +* [Edinburgh](https://www.meetup.com/react-edinburgh/) + ## Spain {/*spain*/} * [Barcelona](https://www.meetup.com/ReactJS-Barcelona/) diff --git a/src/content/community/videos.md b/src/content/community/videos.md index 3fe0d7192..d33bd8160 100644 --- a/src/content/community/videos.md +++ b/src/content/community/videos.md @@ -8,6 +8,75 @@ Vídeos dedicados à discussão do React e do ecossistema do React. +## React Conf 2024 {/*react-conf-2024*/} + +At React Conf 2024, Meta CTO [Andrew "Boz" Bosworth](https://www.threads.net/@boztank) shared a welcome message to kick off the conference: + + + +### React 19 Keynote {/*react-19-keynote*/} + +In the Day 1 keynote, we shared vision for React starting with React 19 and the React Compiler. Watch the full keynote from [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Andrew Clark](https://twitter.com/acdlite), [Josh Story](https://twitter.com/joshcstory), [Sathya Gunasekaran](https://twitter.com/_gsathya), and [Mofei Zhang](https://twitter.com/zmofei): + + + + +### React Unpacked: A Roadmap to React 19 {/*react-unpacked-a-roadmap-to-react-19*/} + +React 19 introduced new features including Actions, `use()`, `useOptimistic` and more. For a deep dive on using new features in React 19, see [Sam Selikoff's](https://twitter.com/samselikoff) talk: + + + +### What's New in React 19 {/*whats-new-in-react-19*/} + +[Lydia Hallie](https://twitter.com/lydiahallie) gave a visual deep dive of React 19's new features: + + + +### React 19 Deep Dive: Coordinating HTML {/*react-19-deep-dive-coordinating-html*/} + +[Josh Story](https://twitter.com/joshcstory) provided a deep dive on the document and resource streaming APIs in React 19: + + + +### React for Two Computers {/*react-for-two-computers*/} + +[Dan Abramov](https://bsky.app/profile/danabra.mov) imagined an alternate history where React started server-first: + + + +### Forget About Memo {/*forget-about-memo*/} + +[Lauren Tan](https://twitter.com/potetotes) gave a talk on using the React Compiler in practice: + + + +### React Compiler Deep Dive {/*react-compiler-deep-dive*/} + +[Sathya Gunasekaran](https://twitter.com/_gsathya) and [Mofei Zhang](https://twitter.com/zmofei) provided a deep dive on how the React Compiler works: + + + +### And more... {/*and-more-2024*/} + +**We also heard talks from the community on Server Components:** +* [Enhancing Forms with React Server Components](https://www.youtube.com/embed/0ckOUBiuxVY&t=25280s) by [Aurora Walberg Scharff](https://twitter.com/aurorascharff) +* [And Now You Understand React Server Components](https://www.youtube.com/embed/pOo7x8OiAec) by [Kent C. Dodds](https://twitter.com/kentcdodds) +* [Real-time Server Components](https://www.youtube.com/embed/6sMANTHWtLM) by [Sunil Pai](https://twitter.com/threepointone) + +**Talks from React frameworks using new features:** + +* [Vanilla React](https://www.youtube.com/embed/ZcwA0xt8FlQ) by [Ryan Florence](https://twitter.com/ryanflorence) +* [React Rhythm & Blues](https://www.youtube.com/embed/rs9X5MjvC4s) by [Lee Robinson](https://twitter.com/leeerob) +* [RedwoodJS, now with React Server Components](https://www.youtube.com/embed/sjyY4MTECUU) by [Amy Dutton](https://twitter.com/selfteachme) +* [Introducing Universal React Server Components in Expo Router](https://www.youtube.com/embed/djhEgxQf3Kw) by [Evan Bacon](https://twitter.com/Baconbrix) + +**And Q&As with the React and React Native teams:** +- [React Q&A](https://www.youtube.com/embed/T8TZQ6k4SLE&t=27518s) hosted by [Michael Chan](https://twitter.com/chantastic) +- [React Native Q&A](https://www.youtube.com/embed/0ckOUBiuxVY&t=27935s) hosted by [Jamon Holmgren](https://twitter.com/jamonholmgren) + +You can watch all of the talks at React Conf 2024 at [conf2024.react.dev](https://conf2024.react.dev/talks). + ## React Conf 2021 {/*react-conf-2021*/} ### React 18 Keynote {/*react-18-keynote*/} @@ -16,13 +85,13 @@ Na palestra principal, compartilhamos nossa visão para o futuro do React começ Assista à palestra completa de [Andrew Clark](https://twitter.com/acdlite), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes) e [Rick Hanlon](https://twitter.com/rickhanlonii) aqui: - + ### React 18 para Desenvolvedores de Aplicativos {/*react-18-for-application-developers*/} Para uma demonstração da atualização para o React 18, veja a palestra de [Shruti Kapoor](https://twitter.com/shrutikapoor08) aqui: - + ### Streaming Server Rendering com Suspense {/*streaming-server-rendering-with-suspense*/} @@ -32,7 +101,7 @@ A renderização streaming do servidor permite que você gere HTML a partir de c Para um mergulho profundo, veja a palestra de [Shaundai Person](https://twitter.com/shaundai) aqui: - + ### The first React working group {/*the-first-react-working-group*/} @@ -40,7 +109,7 @@ Para o React 18, criamos nosso primeiro Grupo de Trabalho para colaborar com um Para uma visão geral deste trabalho, veja a palestra de [Aakansha' Doshi](https://twitter.com/aakansha1216): - + ### React Developer Tooling {/*react-developer-tooling*/} @@ -48,19 +117,19 @@ Para dar suporte aos novos recursos desta versão, também anunciamos a recém-f Para mais informações e uma demonstração dos novos recursos do DevTools, veja a palestra de [Brian Vaughn](https://twitter.com/brian_d_vaughn): - + ### React without memo {/*react-without-memo*/} Olhando para o futuro, [Xuan Huang (黄玄)](https://twitter.com/Huxpro) compartilhou uma atualização da nossa pesquisa do React Labs em um compilador de auto-memoização. Confira esta palestra para obter mais informações e uma demonstração do protótipo do compilador: - + ### React docs keynote {/*react-docs-keynote*/} [Rachel Nabors](https://twitter.com/rachelnabors) iniciou uma seção de palestras sobre aprendizado e design com React com uma palestra sobre nosso investimento nos novos docs do React ([agora enviados como react.dev](/blog/2023/03/16/introducing-react-dev)): - + ### And more... {/*and-more*/} diff --git a/src/content/learn/build-a-react-app-from-scratch.md b/src/content/learn/build-a-react-app-from-scratch.md index d4f4bff4f..a7c578cae 100644 --- a/src/content/learn/build-a-react-app-from-scratch.md +++ b/src/content/learn/build-a-react-app-from-scratch.md @@ -138,4 +138,4 @@ Usar a estratégia de renderização certa para as rotas certas pode diminuir o Estes são apenas alguns exemplos das funcionalidades que uma nova aplicação precisará considerar ao construir do zero. Muitas limitações que você encontrará podem ser difíceis de resolver, já que cada problema está interconectado com os outros e pode requerer expertise profunda em áreas problemáticas com as quais você pode não estar familiarizado. -Se você não quer resolver esses problemas por conta própria, pode [começar com um framework](/learn/creating-a-react-app) que fornece essas funcionalidades prontas para uso. \ No newline at end of file +Se você não quer resolver esses problemas por conta própria, pode [começar com um framework](/learn/creating-a-react-app) que fornece essas funcionalidades prontas para uso. diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index 2053f936b..2d1ee8685 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -211,7 +211,7 @@ This is because **Hooks must only be called at the top-level of your component.* One possible way around this is to get a single ref to their parent element, and then use DOM manipulation methods like [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to "find" the individual child nodes from it. However, this is brittle and can break if your DOM structure changes. -Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and with `null` when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID. +Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and call the cleanup function returned from the callback when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID. This example shows how you can use this approach to scroll to an arbitrary node in a long list: @@ -247,13 +247,13 @@ export default function CatFriends() {
    {catList.map((cat) => (
  • { const map = getMap(); map.set(cat, node); @@ -263,7 +263,7 @@ export default function CatFriends() { }; }} > - +
  • ))}
@@ -273,11 +273,22 @@ export default function CatFriends() { } function setupCatList() { - const catList = []; - for (let i = 0; i < 10; i++) { - catList.push("https://loremflickr.com/320/240/cat?lock=" + i); + const catCount = 10; + const catList = new Array(catCount) + for (let i = 0; i < catCount; i++) { + let imageUrl = ''; + if (i < 5) { + imageUrl = "https://placecats.com/neo/320/240"; + } else if (i < 8) { + imageUrl = "https://placecats.com/millie/320/240"; + } else { + imageUrl = "https://placecats.com/bella/320/240"; + } + catList[i] = { + id: i, + imageUrl, + }; } - return catList; } @@ -876,12 +887,30 @@ export default function CatFriends() { ); } -const catList = []; -for (let i = 0; i < 10; i++) { - catList.push({ +const catCount = 10; +const catList = new Array(catCount); +for (let i = 0; i < catCount; i++) { + const bucket = Math.floor(Math.random() * catCount) % 2; + let imageUrl = ''; + switch (bucket) { + case 0: { + imageUrl = "https://placecats.com/neo/250/200"; + break; + } + case 1: { + imageUrl = "https://placecats.com/millie/250/200"; + break; + } + case 2: + default: { + imageUrl = "https://placecats.com/bella/250/200"; + break; + } + } + catList[i] = { id: i, - imageUrl: 'https://loremflickr.com/250/200/cat?lock=' + i - }); + imageUrl, + }; } ``` @@ -961,7 +990,7 @@ export default function CatFriends() { behavior: 'smooth', block: 'nearest', inline: 'center' - }); + }); }}> Next @@ -993,12 +1022,30 @@ export default function CatFriends() { ); } -const catList = []; -for (let i = 0; i < 10; i++) { - catList.push({ +const catCount = 10; +const catList = new Array(catCount); +for (let i = 0; i < catCount; i++) { + const bucket = Math.floor(Math.random() * catCount) % 2; + let imageUrl = ''; + switch (bucket) { + case 0: { + imageUrl = "https://placecats.com/neo/250/200"; + break; + } + case 1: { + imageUrl = "https://placecats.com/millie/250/200"; + break; + } + case 2: + default: { + imageUrl = "https://placecats.com/bella/250/200"; + break; + } + } + catList[i] = { id: i, - imageUrl: 'https://loremflickr.com/250/200/cat?lock=' + i - }); + imageUrl, + }; } ``` diff --git a/src/content/learn/react-compiler/installation.md b/src/content/learn/react-compiler/installation.md index 9caf19e9b..c20a56c5b 100644 --- a/src/content/learn/react-compiler/installation.md +++ b/src/content/learn/react-compiler/installation.md @@ -175,16 +175,7 @@ Instale o plugin ESLint: npm install -D eslint-plugin-react-hooks@rc -Em seguida, habilite a regra do compilador na sua configuração ESLint: - -```js {3} -// .eslintrc.js -module.exports = { - rules: { - 'react-hooks/react-compiler': 'error', - }, -}; -``` +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). A regra do compilador está habilitada por padrão no RC mais recente, então nenhuma configuração adicional é necessária. A regra ESLint irá: - Identificar violações das [Regras do React](/reference/rules) @@ -254,4 +245,4 @@ Agora que você tem o React Compiler instalado, saiba mais sobre: - [Opções de configuração](/reference/react-compiler/configuration) para personalizar o compilador - [Estratégias de adoção incremental](/learn/react-compiler/incremental-adoption) para bases de código existentes - [Técnicas de depuração](/learn/react-compiler/debugging) para solução de problemas -- [Guia de compilação de bibliotecas](/reference/react-compiler/compiling-libraries) para compilar sua biblioteca React \ No newline at end of file +- [Guia de compilação de bibliotecas](/reference/react-compiler/compiling-libraries) para compilar sua biblioteca React diff --git a/src/content/learn/react-compiler/introduction.md b/src/content/learn/react-compiler/introduction.md index 1a6f4d260..b54c8c332 100644 --- a/src/content/learn/react-compiler/introduction.md +++ b/src/content/learn/react-compiler/introduction.md @@ -50,6 +50,20 @@ const ExpensiveComponent = memo(function ExpensiveComponent({ data, onClick }) { }); ``` + + +Esta memoização manual tem um bug sutil que quebra a memoização: + +```js [[2, 1, "() => handleClick(item)"]] + handleClick(item)} /> +``` + +Mesmo que `handleClick` esteja envolvido em `useCallback`, a função arrow `() => handleClick(item)` cria uma nova função toda vez que o componente renderiza. Isso significa que `Item` sempre receberá uma nova prop `onClick`, quebrando a memoização. + +O React Compiler é capaz de otimizar isso corretamente com ou sem a função arrow, garantindo que `Item` só re-renderize quando `props.onClick` mudar. + + + ### Depois do React Compiler {/*after-react-compiler*/} Com o React Compiler, você escreve o mesmo código sem memoização manual: @@ -154,7 +168,7 @@ Usuários do Next.js podem habilitar o React Compiler invocado pelo swc usando [ ## O que devo fazer sobre useMemo, useCallback e React.memo? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/} -Se você está usando o React Compiler, [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback) e [`React.memo`](/reference/react/memo) podem ser removidos. O React Compiler adiciona memoização automática de forma mais precisa e granular do que é possível com esses hooks. Se você escolher manter a memoização manual, o React Compiler irá analisá-la e determinar se sua memoização manual corresponde à sua memoização automaticamente inferida. Se não houver correspondência, o compilador escolherá não otimizar esse componente. +O React Compiler adiciona memoização automática de forma mais precisa e granular do que é possível com [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback) e [`React.memo`](/reference/react/memo). Se você escolher manter a memoização manual, o React Compiler irá analisá-la e determinar se sua memoização manual corresponde à sua memoização automaticamente inferida. Se não houver correspondência, o compilador escolherá não otimizar esse componente. Isso é feito por precaução, pois um anti-padrão comum com memoização manual é usá-la para correção. Isso significa que sua aplicação depende de valores específicos sendo memoizados para funcionar adequadamente. Por exemplo, para prevenir um loop infinito, você pode ter memoizado alguns valores para impedir que uma chamada `useEffect` seja disparada. Isso quebra as Regras do React, mas como pode ser potencialmente perigoso para o compilador remover automaticamente a memoização manual, o compilador simplesmente não otimizará. Você deve remover manualmente sua memoização escrita à mão e verificar que sua aplicação ainda funciona como esperado. @@ -172,4 +186,4 @@ Esta seção irá ajudá-lo a começar com o React Compiler e entender como usá ## Recursos adicionais {/*additional-resources*/} -Além desta documentação, recomendamos verificar o [Grupo de Trabalho do React Compiler](https://github.com/reactwg/react-compiler) para informações adicionais e discussões sobre o compilador. \ No newline at end of file +Além desta documentação, recomendamos verificar o [Grupo de Trabalho do React Compiler](https://github.com/reactwg/react-compiler) para informações adicionais e discussões sobre o compilador. diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index adc84c847..03a4b11b7 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -1419,10 +1419,29 @@ Similar a um [sistema de design](https://uxdesign.cc/everything-you-need-to-know #### O React fornecerá alguma solução interna para busca de dados? {/*will-react-provide-any-built-in-solution-for-data-fetching*/} -Ainda estamos trabalhando nos detalhes, mas esperamos que no futuro você escreva a busca de dados da seguinte forma: +Hoje, com a API [`use`](/reference/react/use#streaming-data-from-server-to-client), os dados podem ser lidos na renderização passando uma [Promise](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise) para `use`: + +```js {1,4,11} +import { use, Suspense } from "react"; + +function Message({ messagePromise }) { + const messageContent = use(messagePromise); + return

Aqui está a mensagem: {messageContent}

; +} + +export function MessageContainer({ messagePromise }) { + return ( + ⌛Baixando mensagem...

}> + +
+ ); +} +``` + +Estamos ainda trabalhando nos detalhes, mas esperamos que no futuro, você escreva a busca de dados assim: ```js {1,4,6} -import { use } from 'react'; // Não disponível ainda! +import { use } from 'react'; function ShippingForm({ country }) { const cities = use(fetch(`/api/cities?country=${country}`)); diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index c69996282..66a18b2fc 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -283,9 +283,9 @@ No CodeSandbox você verá três seções principais: ![CodeSandbox com código inicial](../images/tutorial/react-starter-code-codesandbox.png) -1. A seção *Arquivos* com uma lista de arquivos como `App.js`, `index.js`, `styles.css` e uma pasta chamada `public` -1. O *editor de código* onde você verá o código fonte de seu arquivo selecionado -1. A seção de *navegador* onde você verá como o código que você escreveu será exibido +1. A seção *Arquivos* com uma lista de arquivos como `App.js`, `index.js`, `styles.css` na pasta `src` e uma pasta chamada `public` +2. O *editor de código* onde você verá o código fonte de seu arquivo selecionado +3. A seção de *navegador* onde você verá como o código que você escreveu será exibido O arquivo `App.js` deve ser selecionado na seção *Arquivos*. Os conteúdos daquele arquivo no *editor de código* devem ser: diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index 9300c8a09..6fd132919 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -32,14 +32,14 @@ Todos os [frameworks React em produção](/learn/start-a-new-react-project#full- Para instalar a versão mais recente das definições de tipos do React: -npm install @types/react @types/react-dom +npm install --save-dev @types/react @types/react-dom As seguintes opções do compilador precisam ser definidas em seu `tsconfig.json`: 1. `dom` precisa ser incluído em [`lib`](https://www.typescriptlang.org/tsconfig/#lib) (Nota: se nenhuma opção de `lib` for especificada, `dom` será incluido por padrão). -1. [`jsx`](https://www.typescriptlang.org/tsconfig/#jsx) deve ser definido como uma das opções válidas. `preserve` deve ser suficiente para a maioria das aplicações. - Se você está publicando uma biblioteca, consulte a [documentação do `jsx`](https://www.typescriptlang.org/tsconfig/#jsx) sobre qual valor escolher. +2. [`jsx`](https://www.typescriptlang.org/tsconfig/#jsx) deve ser definido como uma das opções válidas. `preserve` deve ser suficiente para a maioria das aplicações. + Se você está publicando uma biblioteca, consulte a [documentação do `jsx`](https://www.typescriptlang.org/tsconfig/#jsx) sobre qual valor escolher. ## TypeScript com Componentes React {/*typescript-with-react-components*/} diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index bf3f427af..51bce2ee6 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -38,7 +38,7 @@ Para criar controles interativos para enviar informações, renderize o [compone `
` suporta todas as [props de elementos comuns.](/reference/react-dom/components/common#common-props) -[`action`](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/form#action): uma URL ou função. Quando uma URL é passada para `action`, o formulário se comportará como o componente de formulário HTML. Quando uma função é passada para `action`, a função irá manipular o envio do formulário. A função passada para `action` pode ser async e será chamada com um único argumento contendo os [dados do formulário](https://developer.mozilla.org/pt-BR/docs/Web/API/FormData) do formulário enviado. A prop `action` pode ser substituída por um atributo `formAction` em um componente `