From ebc45f563e9612df7b485ad82324225d554c625b Mon Sep 17 00:00:00 2001 From: Viacheslav Makarov <9768704+mekarthedev@users.noreply.github.com> Date: Fri, 12 May 2023 18:15:37 +0200 Subject: [PATCH 01/67] Remove unnecessary backticks breaking markdown highlighting (#6025) --- src/content/learn/removing-effect-dependencies.md | 4 ++-- src/content/learn/separating-events-from-effects.md | 6 +++--- src/content/learn/updating-objects-in-state.md | 2 +- src/content/reference/react-dom/client/createRoot.md | 4 ++-- src/content/reference/react-dom/client/hydrateRoot.md | 2 +- src/content/reference/react-dom/hydrate.md | 2 +- src/content/reference/react-dom/render.md | 2 +- src/content/reference/react-dom/unmountComponentAtNode.md | 2 +- src/content/reference/react/cloneElement.md | 2 +- src/content/reference/react/createContext.md | 2 +- src/content/reference/react/useEffect.md | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/content/learn/removing-effect-dependencies.md b/src/content/learn/removing-effect-dependencies.md index dc34eedad..0a5151daa 100644 --- a/src/content/learn/removing-effect-dependencies.md +++ b/src/content/learn/removing-effect-dependencies.md @@ -882,7 +882,7 @@ const options2 = { serverUrl: 'https://localhost:1234', roomId: 'music' }; // These are two different objects! console.log(Object.is(options1, options2)); // false -```` +``` **Object and function dependencies can make your Effect re-synchronize more often than you need.** @@ -968,7 +968,7 @@ const roomId2 = 'music'; // These two strings are the same! console.log(Object.is(roomId1, roomId2)); // true -```` +``` Thanks to this fix, the chat no longer re-connects if you edit the input: diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index e932e8afd..a897a602b 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -239,7 +239,7 @@ function ChatRoom({ roomId, theme }) { }); connection.connect(); // ... -```` +``` However, `theme` is a reactive value (it can change as a result of re-rendering), and [every reactive value read by an Effect must be declared as its dependency.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Now you have to specify `theme` as a dependency of your Effect: @@ -256,7 +256,7 @@ function ChatRoom({ roomId, theme }) { }; }, [roomId, theme]); // ✅ All dependencies declared // ... -```` +``` Play with this example and see if you can spot the problem with this user experience: @@ -416,7 +416,7 @@ function ChatRoom({ roomId, theme }) { showNotification('Connected!', theme); }); // ... -```` +``` Here, `onConnected` is called an *Effect Event.* It's a part of your Effect logic, but it behaves a lot more like an event handler. The logic inside it is not reactive, and it always "sees" the latest values of your props and state. diff --git a/src/content/learn/updating-objects-in-state.md b/src/content/learn/updating-objects-in-state.md index 1e23c8d3d..9289f2454 100644 --- a/src/content/learn/updating-objects-in-state.md +++ b/src/content/learn/updating-objects-in-state.md @@ -184,7 +184,7 @@ const nextPosition = {}; nextPosition.x = e.clientX; nextPosition.y = e.clientY; setPosition(nextPosition); -```` +``` In fact, it is completely equivalent to writing this: diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 9121e1d78..d91bc20c6 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -133,7 +133,7 @@ import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')); root.render(); -```` +``` Usually, you only need to run this code once at startup. It will: @@ -395,7 +395,7 @@ root.render(App); // ✅ Correct: is a component. root.render(); -```` +``` Or if you pass a function to `root.render`, instead of the result of calling it: diff --git a/src/content/reference/react-dom/client/hydrateRoot.md b/src/content/reference/react-dom/client/hydrateRoot.md index c875560da..db558bb80 100644 --- a/src/content/reference/react-dom/client/hydrateRoot.md +++ b/src/content/reference/react-dom/client/hydrateRoot.md @@ -127,7 +127,7 @@ If your app's HTML was generated by [`react-dom/server`](/reference/react-dom/cl import { hydrateRoot } from 'react-dom/client'; hydrateRoot(document.getElementById('root'), ); -```` +``` This will hydrate the server HTML inside the browser DOM node with the React component for your app. Usually, you will do it once at startup. If you use a framework, it might do this behind the scenes for you. diff --git a/src/content/reference/react-dom/hydrate.md b/src/content/reference/react-dom/hydrate.md index ab036caa1..639c7ab25 100644 --- a/src/content/reference/react-dom/hydrate.md +++ b/src/content/reference/react-dom/hydrate.md @@ -68,7 +68,7 @@ Call `hydrate` to attach a React component into a import { hydrate } from 'react-dom'; hydrate(, document.getElementById('root')); -```` +``` Using `hydrate()` to render a client-only app (an app without server-rendered HTML) is not supported. Use [`render()`](/reference/react-dom/render) (in React 17 and below) or [`createRoot()`](/reference/react-dom/client/createRoot) (in React 18+) instead. diff --git a/src/content/reference/react-dom/render.md b/src/content/reference/react-dom/render.md index 1a3baead7..a0f751278 100644 --- a/src/content/reference/react-dom/render.md +++ b/src/content/reference/react-dom/render.md @@ -77,7 +77,7 @@ import { render } from 'react-dom'; import App from './App.js'; render(, document.getElementById('root')); -```` +``` ### Rendering the root component {/*rendering-the-root-component*/} diff --git a/src/content/reference/react-dom/unmountComponentAtNode.md b/src/content/reference/react-dom/unmountComponentAtNode.md index e538ceb34..12f11dc74 100644 --- a/src/content/reference/react-dom/unmountComponentAtNode.md +++ b/src/content/reference/react-dom/unmountComponentAtNode.md @@ -64,7 +64,7 @@ render(, rootNode); // ... unmountComponentAtNode(rootNode); -```` +``` ### Removing a React app from a DOM element {/*removing-a-react-app-from-a-dom-element*/} diff --git a/src/content/reference/react/cloneElement.md b/src/content/reference/react/cloneElement.md index 86711f4d8..d6ef84b0a 100644 --- a/src/content/reference/react/cloneElement.md +++ b/src/content/reference/react/cloneElement.md @@ -427,7 +427,7 @@ With this approach, `Row` does not need to receive an `isHighlighted` prop at al export default function Row({ title }) { const isHighlighted = useContext(HighlightContext); // ... -```` +``` This allows the calling component to not know or worry about passing `isHighlighted` to ``: diff --git a/src/content/reference/react/createContext.md b/src/content/reference/react/createContext.md index ff9032aac..a653633c1 100644 --- a/src/content/reference/react/createContext.md +++ b/src/content/reference/react/createContext.md @@ -166,7 +166,7 @@ import { createContext } from 'react'; export const ThemeContext = createContext('light'); export const AuthContext = createContext(null); -```` +``` Components declared in other files can then use the [`import`](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/import) statement to read or provide this context: diff --git a/src/content/reference/react/useEffect.md b/src/content/reference/react/useEffect.md index 8614991ca..dd84fd2ea 100644 --- a/src/content/reference/react/useEffect.md +++ b/src/content/reference/react/useEffect.md @@ -531,7 +531,7 @@ function ChatRoom({ roomId }) { serverUrl: serverUrl }); // ... -```` +``` There are also many excellent custom Hooks for every purpose available in the React ecosystem. From fd8ba03f4d7222ac4813374843a44755fc8c64c4 Mon Sep 17 00:00:00 2001 From: Choi siun Date: Wed, 17 May 2023 03:01:40 +0900 Subject: [PATCH 02/67] docs(types): Fix incorrect period positioning in common.md (#6040) --- src/content/reference/react-dom/components/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index ca16b6a6e..b8b80ea2f 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -156,7 +156,7 @@ nt. * [`title`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title): A string. Specifies the tooltip text for the element. * [`translate`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/translate): Either `'yes'` or `'no'`. Passing `'no'` excludes the element content from being translated. -You can also pass custom attributes as props, for example `mycustomprop="someValue".` This can be useful when integrating with third-party libraries. The custom attribute name must be lowercase and must not start with `on`. The value will be converted to a string. If you pass `null` or `undefined`, the custom attribute will be removed. +You can also pass custom attributes as props, for example `mycustomprop="someValue"`. This can be useful when integrating with third-party libraries. The custom attribute name must be lowercase and must not start with `on`. The value will be converted to a string. If you pass `null` or `undefined`, the custom attribute will be removed. These events fire only for the [`
`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) elements: From bea2ff778d489eb0401eef173a3b7bf74563930e Mon Sep 17 00:00:00 2001 From: vicsantizo <68677648+vicsantizo@users.noreply.github.com> Date: Tue, 16 May 2023 12:01:59 -0600 Subject: [PATCH 03/67] fix(typos): replace word "ever" with "every" (#6039) --- src/content/reference/react-dom/components/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index b8b80ea2f..f1e4fcd0c 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -260,7 +260,7 @@ React will also call your `ref` callback whenever you pass a *different* `ref` c #### Parameters {/*ref-callback-parameters*/} -* `node`: A DOM node or `null`. React will pass you the DOM node when the ref gets attached, and `null` when the ref gets detached. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily detached and re-attached during ever re-render of the component. +* `node`: A DOM node or `null`. React will pass you the DOM node when the ref gets attached, and `null` when the ref gets detached. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily detached and re-attached during every re-render of the component. #### Returns {/*returns*/} From 5bc25d3c36b6e67cd2d86a1145daf6dfa21d4f40 Mon Sep 17 00:00:00 2001 From: Kathryn Middleton Date: Thu, 18 May 2023 12:48:40 -0400 Subject: [PATCH 04/67] Add accessibility note to interactivity section in the new React docs (#6026) * Add accessibility note to interactivity section in the new React docs * Add a11y note to Responding to Events section * Update responding-to-events.md --------- Co-authored-by: dan --- src/content/learn/responding-to-events.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/content/learn/responding-to-events.md b/src/content/learn/responding-to-events.md index 782b6c0f1..4450c4613 100644 --- a/src/content/learn/responding-to-events.md +++ b/src/content/learn/responding-to-events.md @@ -313,6 +313,12 @@ button { margin-right: 10px; } Notice how the `App` component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That's an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they're used later. + + + +Make sure that you use the appropriate HTML tags for your event handlers. For example, to handle clicks, use [`
- - - - React - + + + React
diff --git a/src/components/MDX/BlogCard.tsx b/src/components/MDX/BlogCard.tsx index 9d86f9211..ba610b111 100644 --- a/src/components/MDX/BlogCard.tsx +++ b/src/components/MDX/BlogCard.tsx @@ -16,62 +16,62 @@ export interface BlogCardProps { function BlogCard({title, badge, date, icon, url, children}: BlogCardProps) { return ( - - -
-
-

- {title} -

-
-
-
- {icon === 'labs' && ( - - - - )} - {icon === 'blog' && ( - - - - )} - {date} - {badge ? ( -
- New -
- ) : null} -
- - {children} - - {children != null && ( -
- Read more -
+ +
); } diff --git a/src/components/MDX/Link.tsx b/src/components/MDX/Link.tsx index 8986d07a5..7bf041e56 100644 --- a/src/components/MDX/Link.tsx +++ b/src/components/MDX/Link.tsx @@ -13,7 +13,7 @@ function Link({ className, children, ...props -}: JSX.IntrinsicElements['a']) { +}: React.AnchorHTMLAttributes) { const classes = 'inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal'; const modifiedChildren = Children.toArray(children).map((child: any) => { @@ -41,11 +41,8 @@ function Link({ {modifiedChildren} ) : ( - - {/* eslint-disable-next-line jsx-a11y/anchor-has-content */} - - {modifiedChildren} - + + {modifiedChildren} )} diff --git a/src/components/MDX/Sandpack/DownloadButton.tsx b/src/components/MDX/Sandpack/DownloadButton.tsx index 4181dbe95..4d206fff8 100644 --- a/src/components/MDX/Sandpack/DownloadButton.tsx +++ b/src/components/MDX/Sandpack/DownloadButton.tsx @@ -7,19 +7,22 @@ import {useSandpack} from '@codesandbox/sandpack-react'; import {IconDownload} from '../../Icon/IconDownload'; export interface DownloadButtonProps {} -let supportsImportMap: boolean | void; +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 + let timeout = setTimeout(() => { + supportsImportMap = + (HTMLScriptElement as any).supports && + (HTMLScriptElement as any).supports('importmap'); + cb(); + }, 0); + return () => clearTimeout(timeout); +} function useSupportsImportMap() { - function subscribe() { - // It never updates. - return () => {}; - } function getCurrentValue() { - if (supportsImportMap === undefined) { - supportsImportMap = - (HTMLScriptElement as any).supports && - (HTMLScriptElement as any).supports('importmap'); - } return supportsImportMap; } function getServerSnapshot() { diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 0e8f84f0d..2a9743ec3 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -22,11 +22,7 @@ export interface SearchProps { } function Hit({hit, children}: any) { - return ( - - {children} - - ); + return {children}; } // Copy-pasted from @docsearch/react to avoid importing the whole bundle. diff --git a/yarn.lock b/yarn.lock index 5aa76ffbe..d6e0c82c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -896,10 +896,10 @@ unist-util-visit "^4.0.0" vfile "^5.0.0" -"@next/env@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/env/-/env-12.3.2-canary.7.tgz#98cf3ed5e7d6af93965c708799ac02cb46ca3831" - integrity sha512-uk5yDvh8ra8PlIczZBTZKyt5Rf6a6mH2tGB3hwRAXD5hVLd74LzBQza2aYMEcDlRafAknsbL0dnqI3CkFYat9w== +"@next/env@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.1.tgz#57322da2630b6bb6d7204577b0a18f6f9324db0c" + integrity sha512-eD6WCBMFjLFooLM19SIhSkWBHtaFrZFfg2Cxnyl3vS3DAdFRfnx5TY2RxlkuKXdIRCC0ySbtK9JXXt8qLCqzZg== "@next/eslint-plugin-next@12.0.3": version "12.0.3" @@ -908,70 +908,50 @@ dependencies: glob "7.1.7" -"@next/swc-android-arm-eabi@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.3.2-canary.7.tgz#21811767685d8a58756bbfff23a4e61c8da65a15" - integrity sha512-pusM/ylasGBweiwhINtqWCgy5bOjLmIctFD0etpmh9+DqCg09yu58hJ1Dn/UTW8EbB1nkTP1z3dEoMKLh4fV2A== - -"@next/swc-android-arm64@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.3.2-canary.7.tgz#278e709c31ac5aceebd5e7f66efb81dae40ccab6" - integrity sha512-x11T0ocPE9xrnqMeDzUMepN3P8CHIN8iiLgiFkbTbKTbSciuH3juOvKggJO9APZRG5Ch5eePWcCy2gHedAbhnA== - -"@next/swc-darwin-arm64@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.2-canary.7.tgz#7858ecf88a4e252ef6b66c59e38449a79647e362" - integrity sha512-tcO9hDaMfcbiaZp1B+HZcLzGGs36dnmjQ0YXyn6C88HEUoKyxanYleVHtTmWHlgsxxjZdDd/RzOze1ycWs2oXw== - -"@next/swc-darwin-x64@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.2-canary.7.tgz#9225324b6de548ce7fd21c31d4725910c5b7d136" - integrity sha512-WjAyU67zj69nRM2GNAnBLvghq4EHTyDzMO02GjG6yexVhDvkE0OFlvh0BQLI3DIOz+B3RjJRcW3OoHi8XzW9UA== - -"@next/swc-freebsd-x64@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.2-canary.7.tgz#cf3374f2c3ddf370ed27cac84258760b282b6981" - integrity sha512-cQrdPCMhP1Mc+pIt16FlC5BVgcXzLXRlm7qZ7wBRKG6r/IIIn/qNRFgQQcB3iyvfNZo7lURLKcfsxNmMGclldQ== - -"@next/swc-linux-arm-gnueabihf@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.3.2-canary.7.tgz#b8e82ec743ceadfce25b7e74dfb447913b603c44" - integrity sha512-LEL+dUe10FhQHyXq9Mul5pOJwKDtrAylh9chktWf8eFr14j/YrfPbkLHv1+tCK8brDV3afVJMl0IpoCo75Yfyg== - -"@next/swc-linux-arm64-gnu@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.2-canary.7.tgz#1711f46f004553f3c8ab7546b49e65f88abbbfd6" - integrity sha512-mbDqHk3C76UGIzkOv+G5NslKiSYIXyWQwbkuty0+0wLVJttWjWi2dMN7DFJQPMNvBefU9/vxVJdUnGVGEZfUXw== - -"@next/swc-linux-arm64-musl@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.2-canary.7.tgz#e20b71ce215280bc2cadcf94f9755fdf3ffc0b24" - integrity sha512-gJ3VQHuqb3ABiOKPxfWAJQdO4mp3yNnWIAPN8n52F7Zu38udbHXvcbIylWfQW/Qah+RRf7P7y2txH2kC07QOPA== - -"@next/swc-linux-x64-gnu@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.2-canary.7.tgz#176cf50080f121537877dbdfb7d667be19333a8c" - integrity sha512-/PBLiC+JfMJIzwMCQaSQgnLoIOjdSjTA9zarj2Kk1eCLjH8/VnsfBWtmP7TdbgIRYnZ8QKb4HXSOq94ZQS/fkw== - -"@next/swc-linux-x64-musl@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.2-canary.7.tgz#96b858043d76b87f90b7da43afe13c5942dbceea" - integrity sha512-Bf3goHoUd0SB58sVTMva0ByoLM+aEhm5YJRqsi7SsOAu9EAQwYfWgY2Hx60ah5i1N4ihYK0xjs8kwlfdDVOuow== - -"@next/swc-win32-arm64-msvc@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.2-canary.7.tgz#dd1a36d4afbecc623e71426897cea683a3a75666" - integrity sha512-aPRQ4dY5MuLgHCVdY+/Grgg4oX38pG4S0sT8mpatK3oIdjhj3961cj33QpPAy6dhhCs8m0/eCWYmM9KKlAAUsg== - -"@next/swc-win32-ia32-msvc@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.2-canary.7.tgz#a7455ea57f88345a92c0067e82aa1b7aa5728088" - integrity sha512-hr+TBDICVezyn0HDK4QootalbcuLj9F8qUzZZAw3gHz16rUDpqpnlRjw3RC99AzkKL7qMsdR/+SwnBlBY7ZK7Q== - -"@next/swc-win32-x64-msvc@12.3.2-canary.7": - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.2-canary.7.tgz#4e0d6d567c254e2cf00738f876ddafe5b611ee03" - integrity sha512-1n29b6meb54h/Mw/1xPoJB682nWbtEsUQo7rFJ6G44Nj3fYFXe+XOWQxWu6Sl8yvdBXcZRhRCHuAZGqYtmqorQ== +"@next/swc-darwin-arm64@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.1.tgz#3748040d2dd0d89d3cdcc897f96aeda5130eed8f" + integrity sha512-eF8ARHtYfnoYtDa6xFHriUKA/Mfj/cCbmKb3NofeKhMccs65G6/loZ15a6wYCCx4rPAd6x4t1WmVYtri7EdeBg== + +"@next/swc-darwin-x64@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.1.tgz#c59fc270005f17e04eb7eab4fd68793d0e3409a4" + integrity sha512-7cmDgF9tGWTgn5Gw+vP17miJbH4wcraMHDCOHTYWkO/VeKT73dUWG23TNRLfgtCNSPgH4V5B4uLHoZTanx9bAw== + +"@next/swc-linux-arm64-gnu@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.1.tgz#1aef371bcef5d832d7f7e3aec3e68cfb98282393" + integrity sha512-qwJqmCri2ie8aTtE5gjTSr8S6O8B67KCYgVZhv9gKH44yvc/zXbAY8u23QGULsYOyh1islWE5sWfQNLOj9iryg== + +"@next/swc-linux-arm64-musl@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.1.tgz#2522927cb0af6918405a49f5a1d1687d6847f3ec" + integrity sha512-qcC54tWNGDv/VVIFkazxhqH1Bnagjfs4enzELVRlUOoJPD2BGJTPI7z08pQPbbgxLtRiu8gl2mXvpB8WlOkMeA== + +"@next/swc-linux-x64-gnu@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.1.tgz#5ec9418a35510048a5ceb79ed300463e1a9b312d" + integrity sha512-9TeWFlpLsBosZ+tsm/rWBaMwt5It9tPH8m3nawZqFUUrZyGRfGcI67js774vtx0k3rL9qbyY6+3pw9BCVpaYUA== + +"@next/swc-linux-x64-musl@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.1.tgz#3478b9c89b75c1d0e7def9f35a9a77cb15d1a115" + integrity sha512-sNDGaWmSqTS4QRUzw61wl4mVPeSqNIr1OOjLlQTRuyInxMxtqImRqdvzDvFTlDfdeUMU/DZhWGYoHrXLlZXe6A== + +"@next/swc-win32-arm64-msvc@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.1.tgz#efe53d48ff51d2485eabb910ab7caee78425fc01" + integrity sha512-+CXZC7u1iXdLRudecoUYbhbsXpglYv8KFYsFxKBPn7kg+bk7eJo738wAA4jXIl8grTF2mPdmO93JOQym+BlYGA== + +"@next/swc-win32-ia32-msvc@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.1.tgz#952cdf1c53df46a90d5151d99310195d2c384e55" + integrity sha512-vIoXVVc7UYO68VwVMDKwJC2+HqAZQtCYiVlApyKEeIPIQpz2gpufzGxk1z3/gwrJt/kJ5CDZjlhYDCzd3hdz+g== + +"@next/swc-win32-x64-msvc@13.4.1": + version "13.4.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.1.tgz#447b7dcee5f5d4824cdff331a4ec34b13d0b449d" + integrity sha512-n8V5ImLQZibKTu10UUdI3nIeTLkliEXe628qxqW9v8My3BAH2a7H0SaCqkV2OgqFnn8sG1wxKYw9/SNJ632kSA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1022,10 +1002,10 @@ resolved "https://registry.yarnpkg.com/@stitches/core/-/core-1.2.8.tgz#dce3b8fdc764fbc6dbea30c83b73bfb52cf96173" integrity sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg== -"@swc/helpers@0.4.11": - version "0.4.11" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.11.tgz#db23a376761b3d31c26502122f349a21b592c8de" - integrity sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw== +"@swc/helpers@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.1.tgz#e9031491aa3f26bfcc974a67f48bd456c8a5357a" + integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg== dependencies: tslib "^2.4.0" @@ -1684,6 +1664,13 @@ browserslist@^4.20.2: node-releases "^2.0.6" update-browserslist-db "^1.0.5" +busboy@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -1852,6 +1839,11 @@ cli-truncate@^3.1.0: slice-ansi "^5.0.0" string-width "^5.0.0" +client-only@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + codesandbox-import-util-types@^1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/codesandbox-import-util-types/-/codesandbox-import-util-types-1.3.7.tgz#7a6097e248a75424d13b06b74368cd76bd2b3e10" @@ -4488,31 +4480,28 @@ next-tick@^1.1.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -next@12.3.2-canary.7: - version "12.3.2-canary.7" - resolved "https://registry.yarnpkg.com/next/-/next-12.3.2-canary.7.tgz#c739348174a3d7d97a638aa409376a96577a31d8" - integrity sha512-zUosveWzpeRVy7j4ANoJ4gu0TBrkLYwPlIUEXrqqs/zLpHMu+tanxA1R1ts2d7h/2dSmeVZgGcHiVcHj5uspEA== +next@^13.4.1: + version "13.4.1" + resolved "https://registry.yarnpkg.com/next/-/next-13.4.1.tgz#8d23f94c81b3f9cc8b34165ad528457e5befd726" + integrity sha512-JBw2kAIyhKDpjhEWvNVoFeIzNp9xNxg8wrthDOtMctfn3EpqGCmW0FSviNyGgOSOSn6zDaX48pmvbdf6X2W9xA== dependencies: - "@next/env" "12.3.2-canary.7" - "@swc/helpers" "0.4.11" + "@next/env" "13.4.1" + "@swc/helpers" "0.5.1" + busboy "1.6.0" caniuse-lite "^1.0.30001406" postcss "8.4.14" - styled-jsx "5.0.7" - use-sync-external-store "1.2.0" + styled-jsx "5.1.1" + zod "3.21.4" optionalDependencies: - "@next/swc-android-arm-eabi" "12.3.2-canary.7" - "@next/swc-android-arm64" "12.3.2-canary.7" - "@next/swc-darwin-arm64" "12.3.2-canary.7" - "@next/swc-darwin-x64" "12.3.2-canary.7" - "@next/swc-freebsd-x64" "12.3.2-canary.7" - "@next/swc-linux-arm-gnueabihf" "12.3.2-canary.7" - "@next/swc-linux-arm64-gnu" "12.3.2-canary.7" - "@next/swc-linux-arm64-musl" "12.3.2-canary.7" - "@next/swc-linux-x64-gnu" "12.3.2-canary.7" - "@next/swc-linux-x64-musl" "12.3.2-canary.7" - "@next/swc-win32-arm64-msvc" "12.3.2-canary.7" - "@next/swc-win32-ia32-msvc" "12.3.2-canary.7" - "@next/swc-win32-x64-msvc" "12.3.2-canary.7" + "@next/swc-darwin-arm64" "13.4.1" + "@next/swc-darwin-x64" "13.4.1" + "@next/swc-linux-arm64-gnu" "13.4.1" + "@next/swc-linux-arm64-musl" "13.4.1" + "@next/swc-linux-x64-gnu" "13.4.1" + "@next/swc-linux-x64-musl" "13.4.1" + "@next/swc-win32-arm64-msvc" "13.4.1" + "@next/swc-win32-ia32-msvc" "13.4.1" + "@next/swc-win32-x64-msvc" "13.4.1" nice-try@^1.0.4: version "1.0.5" @@ -5357,13 +5346,13 @@ react-devtools-inline@4.4.0: dependencies: es6-symbol "^3" -react-dom@0.0.0-experimental-cb5084d1c-20220924: - version "0.0.0-experimental-cb5084d1c-20220924" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-cb5084d1c-20220924.tgz#7a8334c5cf4baeb5651ca76fc9eb92ebbaf223bf" - integrity sha512-0IHzPGHESn3uu8nI1w5596GX8bCGCE94DpaHkKSGWOlB6uhoVecU0fyOCkkNuB4cMc9WeOWiH2gsM100EWZDPQ== +react-dom@^0.0.0-experimental-16d053d59-20230506: + version "0.0.0-experimental-16d053d59-20230506" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-16d053d59-20230506.tgz#1870c355f1027262992b2226191810ba15eedab3" + integrity sha512-I4PIT9ZAdDgpbav9BxfzPv2p5otJz6BEbFEBvFwd1BnQJmtkKKApUU7RYdGKnwY2/r6hdfxPm2pne+NhiyBkzg== dependencies: loose-envify "^1.1.0" - scheduler "0.0.0-experimental-cb5084d1c-20220924" + scheduler "0.0.0-experimental-16d053d59-20230506" react-is@^16.13.1: version "16.13.1" @@ -5375,10 +5364,10 @@ react-is@^17.0.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react@0.0.0-experimental-cb5084d1c-20220924: - version "0.0.0-experimental-cb5084d1c-20220924" - resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-cb5084d1c-20220924.tgz#ab661af674be824ae2989467506443b8bc4318d3" - integrity sha512-66AdfxkJrwCaCEKT0LQRd9J9GQ9T+yN7Wx9XT+tNxKycYQ0Exm+DZxOTedagWDlsFMXroyhrTWzgdC18R2PaOQ== +react@^0.0.0-experimental-16d053d59-20230506: + version "0.0.0-experimental-16d053d59-20230506" + resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-16d053d59-20230506.tgz#98a7a9d19ab1820f882111ce4fc4e23f3cb8aaad" + integrity sha512-8PdloFcanNcryJLohpr4rVQfB4oJvsL0Z+TzJ8B66RxauwF95QqUNorGsK1heESrtj4As0oHCmiZkoYzA4uW8w== dependencies: loose-envify "^1.1.0" @@ -5709,10 +5698,10 @@ safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scheduler@0.0.0-experimental-cb5084d1c-20220924: - version "0.0.0-experimental-cb5084d1c-20220924" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-cb5084d1c-20220924.tgz#9986680e1fbf7e4ccfe7606fef5920939d3a1abe" - integrity sha512-SeszKCdhM5OHxNMStjpKIAaloARUMZqIpDZjkZeGuRsyr7YlAqvlsCXyee4ZQOOU1pbr7BIvQntKy5Hil+DQJA== +scheduler@0.0.0-experimental-16d053d59-20230506: + version "0.0.0-experimental-16d053d59-20230506" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-16d053d59-20230506.tgz#cb76957af2849452a5e40c82fb53168da255e32f" + integrity sha512-gGnyU4CkC/+msd1dOQW9zuquI3GoEziuS42soP0AvbTCvRkeU4qhR/mRRaU+/a7JK/OFeSSudcz7enkrkZdSPA== dependencies: loose-envify "^1.1.0" @@ -5941,6 +5930,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -6066,10 +6060,12 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -styled-jsx@5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.7.tgz#be44afc53771b983769ac654d355ca8d019dff48" - integrity sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA== +styled-jsx@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" + integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== + dependencies: + client-only "0.0.1" supports-color@^5.3.0: version "5.5.0" @@ -6494,11 +6490,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-sync-external-store@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -6684,6 +6675,11 @@ yaml@^1.10.0, yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +zod@3.21.4: + version "3.21.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" + integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== + zwitch@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.2.tgz#91f8d0e901ffa3d66599756dde7f57b17c95dce1" From f4bf6811ee52813162fae343117accfeef95d8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Surdi?= Date: Mon, 22 May 2023 09:41:14 -0300 Subject: [PATCH 06/67] docs(pt-br): translated passing-props-to-a-component.md (#676) * docs(pt-br): translated passing-props-to-a-component.md * docs(pt-br): fix missing bullet point in * Apply suggestions from code review Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Update src/content/learn/passing-props-to-a-component.md Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Update src/content/learn/passing-props-to-a-component.md * Update src/content/learn/passing-props-to-a-component.md Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Update src/content/learn/passing-props-to-a-component.md * Apply suggestions from code review * Update src/content/learn/passing-props-to-a-component.md Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> * Update src/content/learn/passing-props-to-a-component.md Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> --------- Co-authored-by: juliane nagao <615616+junagao@users.noreply.github.com> --- .../learn/passing-props-to-a-component.md | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/src/content/learn/passing-props-to-a-component.md b/src/content/learn/passing-props-to-a-component.md index da5fc5efc..3823fd748 100644 --- a/src/content/learn/passing-props-to-a-component.md +++ b/src/content/learn/passing-props-to-a-component.md @@ -1,26 +1,26 @@ --- -title: Passing Props to a Component +title: Passando Props a um Componente --- -React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions. +Componentes do React usam *props* para se comunicar um com ou outro. Todo componente pai pode passar alguma informação aos seus filhos por meio das *props*. Props podem te lembrar de atributos HTML, mas você pode passar qualquer valor JavaScript por meio delas, incluindo objetos, arrays, e funções. -* How to pass props to a component -* How to read props from a component -* How to specify default values for props -* How to pass some JSX to a component -* How props change over time +* Como passar props para um componente +* Como ler props de um componente +* Como especificar valores padrão para as props +* Como passar JSX a um componente +* Como as props mudam com o tempo -## Familiar props {/*familiar-props*/} +## Props familiares {/*familiar-props*/} -Props are the information that you pass to a JSX tag. For example, `className`, `src`, `alt`, `width`, and `height` are some of the props you can pass to an ``: +Props são as informações que você passa usando uma tag JSX. Por exemplo, `className`, `src`, `alt`, `width`, e `height` são algumas das props que você pode passar a uma ``: @@ -51,11 +51,11 @@ body { min-height: 120px; } -The props you can pass to an `` tag are predefined (ReactDOM conforms to [the HTML standard](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). But you can pass any props to *your own* components, such as ``, to customize them. Here's how! +As props que você pode passar a uma tag `` são predefinidas (A ReactDOM conforma-se ao [padrão HTML](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). Mas você pode passar quaisquer props aos *seus próprios* componentes, como um ``, para customizá-los. Veja como fazer isso! -## Passing props to a component {/*passing-props-to-a-component*/} +## Passando props para um componente {/*passing-props-to-a-component*/} -In this code, the `Profile` component isn't passing any props to its child component, `Avatar`: +Neste código, o componente `Profile` não está passando nenhuma prop ao seu componente filho, `Avatar`: ```js export default function Profile() { @@ -65,11 +65,11 @@ export default function Profile() { } ``` -You can give `Avatar` some props in two steps. +Você pode atribuir algumas props ao `Avatar` em dois passos. -### Step 1: Pass props to the child component {/*step-1-pass-props-to-the-child-component*/} +### Passo 1: Passe props ao componente filho {/*step-1-pass-props-to-the-child-component*/} -First, pass some props to `Avatar`. For example, let's pass two props: `person` (an object), and `size` (a number): +Primeiro, passe algumas props ao `Avatar`. Por exemplo, vamos passar duas props: `person` (um objeto), e `size` (um número): ```js export default function Profile() { @@ -84,25 +84,25 @@ export default function Profile() { -If double curly braces after `person=` confuse you, recall [they're merely an object](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx) inside the JSX curlies. +Se as chaves duplas depois de `person=` confundirem você, lembre-se [que elas são meramente um objeto](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx) dentro das chaves da JSX. -Now you can read these props inside the `Avatar` component. +Agora você pode ler essas props dentro do componente `Avatar`. -### Step 2: Read props inside the child component {/*step-2-read-props-inside-the-child-component*/} +### Passo 2: Leia props dentro de um componente filho {/*step-2-read-props-inside-the-child-component*/} -You can read these props by listing their names `person, size` separated by the commas inside `({` and `})` directly after `function Avatar`. This lets you use them inside the `Avatar` code, like you would with a variable. +Você pode ler estas props listando seus nomes `person, size` separados por vírgulas dentro de `({` e `})` diretamente depois de `function Avatar`. Isso permite que você as use dentro do código de `Avatar`, assim como você faria com uma variável. ```js function Avatar({ person, size }) { - // person and size are available here + // person e size estão disponíveis aqui } ``` -Add some logic to `Avatar` that uses the `person` and `size` props for rendering, and you're done. +Adicione alguma lógica a `Avatar` que use as props `person` e `size` para a renderização, e pronto. -Now you can configure `Avatar` to render in many different ways with different props. Try tweaking the values! +Agora você pode configurar `Avatar` para que seja renderizado de várias maneiras diferentes usando props diferentes. Tente mudar os valores! @@ -168,9 +168,9 @@ body { min-height: 120px; } -Props let you think about parent and child components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`. +Props permitem que você pense sobre os componentes pai e filho independentemente. Por exemplo, você pode mudar as props `person` ou `size` dentro de `Profile` sem ter que pensar sobre como `Avatar` as usa. Similarmente, você é livre para mudar como `Avatar` usa essas props, sem checar o `Profile`. -You can think of props like "knobs" that you can adjust. They serve the same role as arguments serve for functions—in fact, props _are_ the only argument to your component! React component functions accept a single argument, a `props` object: +Você pode pensar nas props como "controles" os quais você pode ajustar. Elas desempenham o mesmo papel que os argumentos para funções-de fato, props _são_ o único argumento para o seu componente! Os componente funcionais do React aceitam apenas um argumento, um objeto `props`: ```js function Avatar(props) { @@ -180,11 +180,11 @@ function Avatar(props) { } ``` -Usually you don't need the whole `props` object itself, so you destructure it into individual props. +Normalmente você não precisa de todo o objeto `props` em si, então você pode desestruturá-lo em props individuais. -**Don't miss the pair of `{` and `}` curlies** inside of `(` and `)` when declaring props: +**Não esqueça o par de `{` e `}` chaves** dentro de `(` e `)` ao declarar props: ```js function Avatar({ person, size }) { @@ -192,7 +192,7 @@ function Avatar({ person, size }) { } ``` -This syntax is called ["destructuring"](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter) and is equivalent to reading properties from a function parameter: +Esta sintaxe é chamada de ["desestruturação"](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter) e é equivalente a ler propriedades de um parâmetro de função: ```js function Avatar(props) { @@ -204,9 +204,9 @@ function Avatar(props) { -## Specifying a default value for a prop {/*specifying-a-default-value-for-a-prop*/} +## Especificando um valor padrão para uma prop {/*specifying-a-default-value-for-a-prop*/} -If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting `=` and the default value right after the parameter: +Se você quer dar a uma prop um valor padrão para usar quando nenhum valor for especificado, pode fazer isso com a desestruturação colocando `=` e o valor padrão logo depois do parâmetro: ```js function Avatar({ person, size = 100 }) { @@ -214,13 +214,13 @@ function Avatar({ person, size = 100 }) { } ``` -Now, if `` is rendered with no `size` prop, the `size` will be set to `100`. +Agora, se `` for renderizado sem a prop `size`, `size` será igual a `100`. -The default value is only used if the `size` prop is missing or if you pass `size={undefined}`. But if you pass `size={null}` or `size={0}`, the default value will **not** be used. +O valor padrão é apenas utilizado se a prop `size` não for especificada ou se você passar `size={undefined}`. Mas caso você passe `size={null}` ou `size={0}`, o valor padrão **não** será usado. -## Forwarding props with the JSX spread syntax {/*forwarding-props-with-the-jsx-spread-syntax*/} +## Encaminhando props com a sintaxe de espalhamento JSX {/*forwarding-props-with-the-jsx-spread-syntax*/} -Sometimes, passing props gets very repetitive: +Às vezes, passar props se torna muito repetitivo: ```js function Profile({ person, size, isSepia, thickBorder }) { @@ -237,7 +237,7 @@ function Profile({ person, size, isSepia, thickBorder }) { } ``` -There's nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don't use any of their props directly, it can make sense to use a more concise "spread" syntax: +Não há nada de errado com código repetitivo-ele pode ser mais legível. Mas às vezes você pode valorizar concisão. Alguns componentes encaminham todas as suas props aos seus filhos, como `Profile` faz com `Avatar`. Como eles não usam nenhuma de suas props diretamente, pode fazer sentido usar uma sintaxe de espalhamento mais concisa: ```js function Profile(props) { @@ -249,13 +249,13 @@ function Profile(props) { } ``` -This forwards all of `Profile`'s props to the `Avatar` without listing each of their names. +Isso encaminha todas as props de `Profile` ao `Avatar` sem listar cada um de seus nomes. -**Use spread syntax with restraint.** If you're using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next! +**Use a sintaxe de espalhamento com cuidado.** Se você está a utilizando em quase todos os componentes, algo está errado. Muitas vezes, isso indica que você deveria dividir seus componentes e passar filhos como JSX. Mais sobre isso a seguir! -## Passing JSX as children {/*passing-jsx-as-children*/} +## Passando JSX como `children` {/*passing-jsx-as-children*/} -It is common to nest built-in browser tags: +É comum aninhar tags embutidas no navegador: ```js
@@ -263,7 +263,7 @@ It is common to nest built-in browser tags:
``` -Sometimes you'll want to nest your own components the same way: +Às vezes você desejará aninhar seus próprios componentes da mesma forma: ```js @@ -271,7 +271,7 @@ Sometimes you'll want to nest your own components the same way: ``` -When you nest content inside a JSX tag, the parent component will receive that content in a prop called `children`. For example, the `Card` component below will receive a `children` prop set to `` and render it in a wrapper div: +Quando você aninha conteúdo dentro de uma tag JSX, o componente pai irá receber esse conteúdo em uma prop chamada `children`. Por exemplo, o componente `Card` abaixo receberá a prop `children` definida como `` e o renderizará em uma wrapper div: @@ -347,17 +347,17 @@ export function getImageUrl(person, size = 's') { -Try replacing the `` inside `` with some text to see how the `Card` component can wrap any nested content. It doesn't need to "know" what's being rendered inside of it. You will see this flexible pattern in many places. +Tente substituir o `` dentro de `` com algum texto para ver como o componente `Card` pode encapsular conteúdo aninhado. Ele não precisa "saber" o que está sendo renderizado dentro dele. Você encontrará esse padrão flexível em muitos lugares. -You can think of a component with a `children` prop as having a "hole" that can be "filled in" by its parent components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, etc. +É possível pensar sobre um componente com a prop `children` como se ele tivesse um "buraco" o qual pode ser "preenchido" por seus componente pais com JSX arbitrária. Você frequentemente usará a prop `children` para wrappers visuais: painéis, grids, etc. -## How props change over time {/*how-props-change-over-time*/} +## Como props mudam com o passar do tempo {/*how-props-change-over-time*/} -The `Clock` component below receives two props from its parent component: `color` and `time`. (The parent component's code is omitted because it uses [state](/learn/state-a-components-memory), which we won't dive into just yet.) +O componente `Clock` abaixo recebe duas props de seu componente pai: `color` e `time`. (O código deste componente pai está omitido porque usa [state](/learn/state-a-components-memory), conceito o qual nós não vamos nos aprofundar ainda.) -Try changing the color in the select box below: +Tente mudar a cor na caixa de seleção abaixo: @@ -392,7 +392,7 @@ export default function App() { return (

- Pick a color:{' '} + Escolha uma cor:{' '} `, updating its `value`, but the text doesn't disappear when the component re-renders: +**O React apenas altera os nós do DOM se houver uma diferença entre as renderizações.** Por exemplo, aqui está um componente que renderiza novamente com props diferentes passados de seu pai a cada segundo. Observe como você pode adicionar algum texto no ``, atualizando seu `valor`, mas o texto não desaparece quando o componente renderiza novamente: @@ -193,21 +193,20 @@ export default function App() { -This works because during this last step, React only updates the content of `

` with the new `time`. It sees that the `` appears in the JSX in the same place as last time, so React doesn't touch the ``—or its `value`! -## Epilogue: Browser paint {/*epilogue-browser-paint*/} +Isso funciona porque durante esta última etapa, o React apenas atualiza o conteúdo de `

` com o novo `time`. Ele vê que o `` aparece no JSX no mesmo lugar da última vez, então o React não toca no ``—ou no seu `value`! +## Epílogo: pintura do Navegador {/*epilogue-browser-paint*/} -After rendering is done and React updated the DOM, the browser will repaint the screen. Although this process is known as "browser rendering", we'll refer to it as "painting" to avoid confusion throughout the docs. +Após a renderização ser concluída e o React atualizar o DOM, o navegador irá repintar a tela. Embora esse processo seja conhecido como "renderização do navegador", vamos nos referir a ele como "pintura" para evitar confusão ao longo dos documentos. - + -* Any screen update in a React app happens in three steps: - 1. Trigger - 2. Render - 3. Commit -* You can use Strict Mode to find mistakes in your components -* React does not touch the DOM if the rendering result is the same as last time +* Qualquer atualização de tela em um app React ocorre em três etapas: + 1. Acionar + 2. Renderizar + 3. Confirmar +* Você pode usar o Modo Estrito (Strict Mode) para encontrar erros em seus componentes +* O React não toca no DOM se o resultado da renderização for o mesmo da última vez - From 5715d09ab0bf6726637883b4a295e1a55855c323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renato=20B=C3=B6hler?= Date: Mon, 22 May 2023 09:54:49 -0300 Subject: [PATCH 09/67] Adds new common translation terms to `GLOSSARY.md` (#681) * Adds new common translation terms * Adds translation suggestion for "caveats" --- GLOSSARY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GLOSSARY.md b/GLOSSARY.md index 2ce2caf7d..19ff920aa 100644 --- a/GLOSSARY.md +++ b/GLOSSARY.md @@ -105,9 +105,11 @@ Sugestões de palavras e termos: | Palavra/Termo original | Sugestão | | ---------------------- | -------------------------------------- | | assertion | asserção | +| at the top level | na raiz | | browser | navegador | | bubbling | propagar | | bug | erro | +| caveats | ressalvas | | class component | componente de classe | | class | classe | | client | cliente | @@ -136,6 +138,7 @@ Sugestões de palavras e termos: | stateful logic | lógica com estado | | to assert | afirmar | | to wrap | encapsular | +| troubleshooting | solução de problemas | | uncontrolled component | componente não controlado | | uppercase | maiúscula(s) / caixa alta | From 331206a4bd13330fae04c6dd6cc9ad2811deedd3 Mon Sep 17 00:00:00 2001 From: Kevin Cubas <61201131+kevinCubas@users.noreply.github.com> Date: Mon, 22 May 2023 14:36:08 -0300 Subject: [PATCH 10/67] Translate Fragment.md (#680) * update(translation): translate Fragment component path: src\content\reference\react\Fragment.md * fix: remove english lines * fix: grammar typos * fix: break lines between sections Co-authored-by: Jhon Mike * Update Fragment.md --------- Co-authored-by: Jhon Mike --- src/content/reference/react/Fragment.md | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/content/reference/react/Fragment.md b/src/content/reference/react/Fragment.md index aa72b08a0..1d0848b22 100644 --- a/src/content/reference/react/Fragment.md +++ b/src/content/reference/react/Fragment.md @@ -4,7 +4,7 @@ title: (<>...) -``, often used via `<>...` syntax, lets you group elements without a wrapper node. +``, frequentemente usado por meio da sintaxe `<>...`, permite agrupar elementos sem um nó de encapsulamento. ```js <> @@ -19,29 +19,29 @@ title: (<>...) --- -## Reference {/*reference*/} +## Referência {/*reference*/} ### `` {/*fragment*/} -Wrap elements in `` to group them together in situations where you need a single element. Grouping elements in `Fragment` has no effect on the resulting DOM; it is the same as if the elements were not grouped. The empty JSX tag `<>` is shorthand for `` in most cases. +Encapsule elementos em `` para agrupá-los juntos em situações em que você precisa de um único elemento. Agrupar elementos em `Fragment` não afeta o DOM resultante; é o mesmo que se os elementos não estivessem agrupados. A tag JSX vazia `<>` é uma forma abreviada de `` na maioria dos casos. #### Props {/*props*/} -- **optional** `key`: Fragments declared with the explicit `` syntax may have [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key) +- **opcional** `key`: Fragments declarados com a sintaxe explícita `` podem ter [keys.](https://pt-br.react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key). -#### Caveats {/*caveats*/} +#### Cuidados {/*caveats*/} -- 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 `...`. +- 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 `...`. -- React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<>` to `[]` or back, or when you go from rendering `<>` to `` and back. This only works a single level deep: for example, going from `<><>` to `` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b) +- O React não [reseta o estado](/learn/preserving-and-resetting-state) quando você passa de `<>` para `[]` ou vice-versa, ou quando você passa de `<>` para `` e vice-versa. Isso funciona apenas para um único nível: por exemplo, passar de `<><>` para `` reseta o estado. Veja a semântica precisa [aqui.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b). --- -## Usage {/*usage*/} +## Uso {/*usage*/} -### Returning multiple elements {/*returning-multiple-elements*/} +### Retornando múltiplos elementos {/*returning-multiple-elements*/} -Use `Fragment`, or the equivalent `<>...` syntax, to group multiple elements together. You can use it to put multiple elements in any place where a single element can go. For example, a component can only return one element, but by using a Fragment you can group multiple elements together and then return them as a group: +Use `Fragment` ou a sintaxe equivalente `<>...` para agrupar vários elementos juntos. Você pode usá-lo para colocar vários elementos em qualquer lugar onde um único elemento possa ir. Por exemplo, um componente só pode retornar um elemento, mas usando um Fragment você pode agrupar vários elementos juntos e então retorná-los como um grupo: ```js {3,6} function Post() { @@ -54,7 +54,7 @@ function Post() { } ``` -Fragments are useful because grouping elements with a Fragment has no effect on layout or styles, unlike if you wrapped the elements in another container like a DOM element. If you inspect this example with the browser tools, you'll see that all `

` and `
` DOM nodes appear as siblings without wrappers around them: +Fragments são úteis porque agrupar elementos com um Fragment não afeta o layout ou os estilos, ao contrário se você envolvesse os elementos em outro container como um elemento do DOM. Se você inspecionar este exemplo com as ferramentas do navegador, verá que todos os nós do DOM `

` e `
` aparecem como irmãos sem encapsulamento ao redor deles: @@ -62,8 +62,8 @@ Fragments are useful because grouping elements with a Fragment has no effect on export default function Blog() { return ( <> - - + + ) } @@ -94,9 +94,9 @@ function PostBody({ body }) { -#### How to write a Fragment without the special syntax? {/*how-to-write-a-fragment-without-the-special-syntax*/} +#### Como escrever um Fragment sem a sintaxe especial? {/*how-to-write-a-fragment-without-the-special-syntax*/} -The example above is equivalent to importing `Fragment` from React: +O exemplo acima é equivalente a importar `Fragment` do React: ```js {1,5,8} import { Fragment } from 'react'; @@ -111,15 +111,15 @@ function Post() { } ``` -Usually you won't need this unless you need to [pass a `key` to your `Fragment`.](#rendering-a-list-of-fragments) +Normalmente, você não precisará disso, a menos que precise [passar uma `key` para o seu `Fragment`.](#rendering-a-list-of-fragments) --- -### Assigning multiple elements to a variable {/*assigning-multiple-elements-to-a-variable*/} +### Atribuindo vários elementos a uma variável {/*assigning-multiple-elements-to-a-variable*/} -Like any other element, you can assign Fragment elements to variables, pass them as props, and so on: +Assim como qualquer outro elemento, você pode atribuir elementos de Fragment a variáveis, passá-los como props, e assim por diante: ```js function CloseDialog() { @@ -131,7 +131,7 @@ function CloseDialog() { ); return ( - Are you sure you want to leave this page? + Você tem certeza que deseja sair desta página? ); } @@ -139,17 +139,17 @@ function CloseDialog() { --- -### Grouping elements with text {/*grouping-elements-with-text*/} +### Agrupando elementos com texto {/*grouping-elements-with-text*/} -You can use `Fragment` to group text together with components: +Você pode usar `Fragment` para agrupar textos juntamente com componentes: ```js function DateRangePicker({ start, end }) { return ( <> - From + De - to + para ); @@ -158,9 +158,9 @@ function DateRangePicker({ start, end }) { --- -### Rendering a list of Fragments {/*rendering-a-list-of-fragments*/} +### Renderizando uma lista de Fragments {/*rendering-a-list-of-fragments*/} -Here's a situation where you need to write `Fragment` explicitly instead of using the `<>` syntax. When you [render multiple elements in a loop](/learn/rendering-lists), you need to assign a `key` to each element. If the elements within the loop are Fragments, you need to use the normal JSX element syntax in order to provide the `key` attribute: +Aqui está uma situação em que você precisa escrever `Fragment` explicitamente em vez de usar a sintaxe `<>`. Quando você [renderiza vários elementos em um loop](https://pt-br.react.dev/learn/rendering-lists), é necessário atribuir uma `key` a cada elemento. Se os elementos dentro do loop forem Fragments, você precisará usar a sintaxe normal de elementos JSX para fornecer o atributo `key`: ```js {3,6} function Blog() { @@ -173,7 +173,7 @@ function Blog() { } ``` -You can inspect the DOM to verify that there are no wrapper elements around the Fragment children: +Você pode inspecionar o DOM para verificar que não há elementos de encapsulamento ao redor dos filhos do Fragment: @@ -181,8 +181,8 @@ You can inspect the DOM to verify that there are no wrapper elements around the import { Fragment } from 'react'; const posts = [ - { id: 1, title: 'An update', body: "It's been a while since I posted..." }, - { id: 2, title: 'My new blog', body: 'I am starting a new blog!' } + { id: 1, title: 'Uma atualização', body: "Faz um tempo desde que eu publiquei..." }, + { id: 2, title: 'Meu novo blog', body: 'Eu estou começando um novo blog!' } ]; export default function Blog() { From 398ace5b5e36535be19e89edd8c4a20db8a3e042 Mon Sep 17 00:00:00 2001 From: Viacheslav Makarov <9768704+mekarthedev@users.noreply.github.com> Date: Tue, 23 May 2023 16:01:09 +0200 Subject: [PATCH 11/67] Add missing 'it' (#6061) --- src/content/reference/react/useEffect.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useEffect.md b/src/content/reference/react/useEffect.md index dd84fd2ea..8d04f205c 100644 --- a/src/content/reference/react/useEffect.md +++ b/src/content/reference/react/useEffect.md @@ -1089,7 +1089,7 @@ function ChatRoom({ roomId }) { } ``` -**To remove a dependency, you need to ["prove" to the linter *doesn't need* to be a dependency.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)** For example, you can move `serverUrl` out of your component to prove that it's not reactive and won't change on re-renders: +**To remove a dependency, you need to ["prove" to the linter that it *doesn't need* to be a dependency.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)** For example, you can move `serverUrl` out of your component to prove that it's not reactive and won't change on re-renders: ```js {1,8} const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore From 09185bcea9c7880763a458e9a68e67e454109791 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Tue, 23 May 2023 23:16:39 +0900 Subject: [PATCH 12/67] Fix a wrong explanation in "Manipulating the DOM with Refs" (#6055) * Fix manipulating-the-dom-with-refs * Update manipulating-the-dom-with-refs.md --------- Co-authored-by: dan --- src/content/learn/manipulating-the-dom-with-refs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index b5c193763..3e91a7694 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -31,7 +31,7 @@ Then, use it to declare a ref inside your component: const myRef = useRef(null); ``` -Finally, pass it to the DOM node as the `ref` attribute: +Finally, pass your ref as the `ref` attribute to the JSX tag for which you want to get the DOM node: ```js
From 9443bae2255b5549a20836c43846568fd9c155a5 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Tue, 23 May 2023 15:37:40 -0300 Subject: [PATCH 13/67] translate Reusing logic with custom hooks to pt-br --- .../learn/reusing-logic-with-custom-hooks.md | 414 +++++++++--------- 1 file changed, 207 insertions(+), 207 deletions(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 679a9bac2..6cef0dba7 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -4,27 +4,27 @@ title: 'Reusing Logic with Custom Hooks' -React comes with several built-in Hooks like `useState`, `useContext`, and `useEffect`. Sometimes, you'll wish that there was a Hook for some more specific purpose: for example, to fetch data, to keep track of whether the user is online, or to connect to a chat room. You might not find these Hooks in React, but you can create your own Hooks for your application's needs. +O React vem com vários Hooks embutidos como `useState`, `useContext`, and `useEffect`. Às vezes, você desejará que houvesse um Hook para algum propósito mais específico: Por exemplo, para buscar dados, para acompanhar se o usuário está online, ou para se conectar a uma sala de bate-papo. Você pode não encontrar esses Hooks no React, mas pode criar seus próprios Hooks para as necessidades do seu aplicativo -- What custom Hooks are, and how to write your own -- How to reuse logic between components -- How to name and structure your custom Hooks -- When and why to extract custom Hooks +- O que são Hooks personalizados e como escrever os seus próprios +- Como reutilizar lógica entre componentes +- Como nomear e estruturar seus Hooks personalizados +- Quando e por que extrair Hooks personalizados -## Custom Hooks: Sharing logic between components {/*custom-hooks-sharing-logic-between-components*/} +## Hooks Personalizados: Compartilhando lógica entre componentes {/*custom-hooks-sharing-logic-between-components*/} -Imagine you're developing an app that heavily relies on the network (as most apps do). You want to warn the user if their network connection has accidentally gone off while they were using your app. How would you go about it? It seems like you'll need two things in your component: +Imagine que você está desenvolvendo um aplicativo que depende fortemente da rede (como a maioria dos aplicativos). Você deseja alertar o usuário caso a conexão de rede seja perdida acidentalmente enquanto eles estiverem usando o seu aplicativo. Como você procederia? Parece que você precisará de duas coisas no seu componente: -1. A piece of state that tracks whether the network is online. -2. An Effect that subscribes to the global [`online`](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) and [`offline`](https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event) events, and updates that state. +1. Um estado que acompanha se a rede está online ou não. +2. Um efeito que se inscreve nos eventos globais [`online`](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) e [`offline`](https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event) e atualiza o estado correspondente. -This will keep your component [synchronized](/learn/synchronizing-with-effects) with the network status. You might start with something like this: +Isso manterá seu componente [sincronizado](/learn/synchronizing-with-effects) com o status da rede. Você pode começar com algo assim: @@ -48,17 +48,17 @@ export default function StatusBar() { }; }, []); - return

{isOnline ? '✅ Online' : '❌ Disconnected'}

; + return

{isOnline ? '✅ Conectado' : '❌ Desconectado'}

; } ```
-Try turning your network on and off, and notice how this `StatusBar` updates in response to your actions. +Tente ligar e desligar sua conexão de rede e observe como esta `StatusBar` é atualizada em resposta às suas ações. -Now imagine you *also* want to use the same logic in a different component. You want to implement a Save button that will become disabled and show "Reconnecting..." instead of "Save" while the network is off. +Agora, imagine que você *também* deseja usar a mesma lógica em um componente diferente. Você deseja implementar um botão "Salvar" que ficará desativado e exibirá "Reconectando..." em vez de "Salvar" enquanto a rede estiver desligada. -To start, you can copy and paste the `isOnline` state and the Effect into `SaveButton`: +Para começar, você pode copiar e colar o estado `isOnline` e o efeito em `SaveButton`: @@ -83,12 +83,12 @@ export default function SaveButton() { }, []); function handleSaveClick() { - console.log('✅ Progress saved'); + console.log('✅ Progresso salvo'); } return ( ); } @@ -96,36 +96,36 @@ export default function SaveButton() { -Verify that, if you turn off the network, the button will change its appearance. +Verifique que, ao desligar a rede, o botão alterará sua aparência. -These two components work fine, but the duplication in logic between them is unfortunate. It seems like even though they have different *visual appearance,* you want to reuse the logic between them. +Esses dois componentes funcionam bem, mas a duplicação da lógica entre eles é infeliz. Parece que, mesmo que eles tenham uma aparência *visual diferente,* você deseja reutilizar a lógica entre eles. -### Extracting your own custom Hook from a component {/*extracting-your-own-custom-hook-from-a-component*/} +### Extraindo seu próprio Hook personalizado de um componente {/*extracting-your-own-custom-hook-from-a-component*/} -Imagine for a moment that, similar to [`useState`](/reference/react/useState) and [`useEffect`](/reference/react/useEffect), there was a built-in `useOnlineStatus` Hook. Then both of these components could be simplified and you could remove the duplication between them: +Imagine, por um momento, que, assim como [`useState`](/reference/react/useState) e [`useEffect`](/reference/react/useEffect), houvesse um Hook embutido chamado `useOnlineStatus`. Em seguida, ambos esses componentes poderiam ser simplificados e seria possível remover a duplicação entre eles: ```js {2,7} function StatusBar() { const isOnline = useOnlineStatus(); - return

{isOnline ? '✅ Online' : '❌ Disconnected'}

; + return

{isOnline ? '✅ Conectado' : '❌ Desconectado'}

; } function SaveButton() { const isOnline = useOnlineStatus(); function handleSaveClick() { - console.log('✅ Progress saved'); + console.log('✅ Progresso salvo'); } return ( ); } ``` -Although there is no such built-in Hook, you can write it yourself. Declare a function called `useOnlineStatus` and move all the duplicated code into it from the components you wrote earlier: +Embora não exista um Hook embutido assim, você pode escrevê-lo por conta própria. Declare uma função chamada `useOnlineStatus` e mova todo o código duplicado para ela, a partir dos componentes que você escreveu anteriormente: ```js {2-16} function useOnlineStatus() { @@ -148,7 +148,7 @@ function useOnlineStatus() { } ``` -At the end of the function, return `isOnline`. This lets your components read that value: +No final da função, retorne `isOnline`. Isso permite que seus componentes leiam esse valor: @@ -157,19 +157,19 @@ import { useOnlineStatus } from './useOnlineStatus.js'; function StatusBar() { const isOnline = useOnlineStatus(); - return

{isOnline ? '✅ Online' : '❌ Disconnected'}

; + return

{isOnline ? '✅ Conectado' : '❌ Desconectado'}

; } function SaveButton() { const isOnline = useOnlineStatus(); function handleSaveClick() { - console.log('✅ Progress saved'); + console.log('✅ Progresso salvo'); } return ( ); } @@ -209,89 +209,89 @@ export function useOnlineStatus() {
-Verify that switching the network on and off updates both components. +Verifique se alternar a rede ligada e desligada atualiza ambos os componentes. -Now your components don't have as much repetitive logic. **More importantly, the code inside them describes *what they want to do* (use the online status!) rather than *how to do it* (by subscribing to the browser events).** +Agora, seus componentes não possuem tanta lógica repetitiva. **Mais importante ainda, o código dentro deles descreve *o que deles desejam fazer* (usar o status online!) em vez de *como fazer isso* (se inscrevendo nos eventos do navegador).** -When you extract logic into custom Hooks, you can hide the gnarly details of how you deal with some external system or a browser API. The code of your components expresses your intent, not the implementation. +Quando você extrai a lógica em Hooks personalizados, é possível ocultar os detalhes complicados de como lidar com algum sistema externo ou uma API do navegador. O código dos seus componentes expressa sua intenção, não a implementação. -### Hook names always start with `use` {/*hook-names-always-start-with-use*/} +### Nome dos hooks sempre começam com `use` {/*hook-names-always-start-with-use*/} -React applications are built from components. Components are built from Hooks, whether built-in or custom. You'll likely often use custom Hooks created by others, but occasionally you might write one yourself! +Aplicações React são construídas a partir de componentes. Os componentes são construídos a partir de Hooks, sejam eles embutidos ou personalizados. Provavelmente, você frequentemente usará Hooks personalizados criados por outras pessoas, mas ocasionalmente poderá escrever um você mesmo! -You must follow these naming conventions: +Você deve seguir estas convenções de nomenclatura: -1. **React component names must start with a capital letter,** like `StatusBar` and `SaveButton`. React components also need to return something that React knows how to display, like a piece of JSX. -2. **Hook names must start with `use` followed by a capital letter,** like [`useState`](/reference/react/useState) (built-in) or `useOnlineStatus` (custom, like earlier on the page). Hooks may return arbitrary values. +1. **Os nomes dos componentes do React devem começar com uma letra maiúscula,** como `StatusBar` e `SaveButton`. Os componentes do React também precisam retornar algo que o React saiba como exibir, como um trecho de JSX. +2. **Os nomes do hooks devem começar com `use` seguido por uma letra maiúscula,** como [`useState`](/reference/react/useState) (built-in) ou `useOnlineStatus` (personalizado, como mencionado anteriormente na página). Hooks podem retornar valores arbitrários. -This convention guarantees that you can always look at a component and know where its state, Effects, and other React features might "hide". For example, if you see a `getColor()` function call inside your component, you can be sure that it can't possibly contain React state inside because its name doesn't start with `use`. However, a function call like `useOnlineStatus()` will most likely contain calls to other Hooks inside! +Essa convenção garante que você sempre possa olhar para um componente e saber onde seu estado, efeitos e outras funcionalidades do React podem estar "escondidos". Por exemplo, se você vir uma chamada de função `getColor()` dentro do seu componente, pode ter certeza de que ela não pode conter estado do React, pois seu nome não começa com `use`. No entanto, uma chamada de função como `useOnlineStatus()` provavelmente conterá chamadas a outros Hooks internamente! -If your linter is [configured for React,](/learn/editor-setup#linting) it will enforce this naming convention. Scroll up to the sandbox above and rename `useOnlineStatus` to `getOnlineStatus`. Notice that the linter won't allow you to call `useState` or `useEffect` inside of it anymore. Only Hooks and components can call other Hooks! +Se o seu linter estiver [configurado para o React,](/learn/editor-setup#linting) ele irá impor essa convenção de nomenclatura. Role para cima até a área de sandbox acima e renomeie `useOnlineStatus` para `getOnlineStatus`. Observe que o linter não permitirá mais que você chame `useState` ou `useEffect` dentro dele. Apenas Hooks e componentes podem chamar outros Hooks! -#### Should all functions called during rendering start with the use prefix? {/*should-all-functions-called-during-rendering-start-with-the-use-prefix*/} +#### Todos os nomes de funções chamadas durante a renderização devem começar com o prefixo use? {/*should-all-functions-called-during-rendering-start-with-the-use-prefix*/} -No. Functions that don't *call* Hooks don't need to *be* Hooks. +Não. Funções que não *chamam* Hooks não precisam *ser* Hooks. -If your function doesn't call any Hooks, avoid the `use` prefix. Instead, write it as a regular function *without* the `use` prefix. For example, `useSorted` below doesn't call Hooks, so call it `getSorted` instead: +Se sua função não chama nenhum Hook, evite o prefixo `use`. Em vez disso, escreva-a como uma função regular *sem* o prefixo `use`. Por exemplo, se a função `useSorted` abaixo não chama Hooks, você pode chamá-la de `getSorted`: ```js -// 🔴 Avoid: A Hook that doesn't use Hooks +// 🔴 Evite: um Hook que não utiliza Hooks function useSorted(items) { return items.slice().sort(); } -// ✅ Good: A regular function that doesn't use Hooks +// ✅ Bom: uma função regular que não utiliza Hooks function getSorted(items) { return items.slice().sort(); } ``` -This ensures that your code can call this regular function anywhere, including conditions: +Isso garante que seu código possa chamar essa função regular em qualquer lugar, incluindo condições: ```js function List({ items, shouldSort }) { let displayedItems = items; if (shouldSort) { - // ✅ It's ok to call getSorted() conditionally because it's not a Hook + // ✅ É possível chamar getSorted() condicionalmente porque não é um Hook. displayedItems = getSorted(items); } // ... } ``` -You should give `use` prefix to a function (and thus make it a Hook) if it uses at least one Hook inside of it: +Você deve adicionar o prefixo `use` a uma função (e, portanto, transformá-la em um Hook) se ela usar pelo menos um Hook em seu interior. ```js -// ✅ Good: A Hook that uses other Hooks +// ✅ Bom: um Hook que usa outros Hooks function useAuth() { return useContext(Auth); } ``` -Technically, this isn't enforced by React. In principle, you could make a Hook that doesn't call other Hooks. This is often confusing and limiting so it's best to avoid that pattern. However, there may be rare cases where it is helpful. For example, maybe your function doesn't use any Hooks right now, but you plan to add some Hook calls to it in the future. Then it makes sense to name it with the `use` prefix: +Tecnicamente, isso não é exigido pelo React. Em princípio, é possível criar um Hook que não chama outros Hooks. Isso geralmente é confuso e limitante, então é melhor evitar esse padrão. No entanto, pode haver casos raros em que isso é útil. Por exemplo, talvez sua função não use nenhum Hook no momento, mas você planeja adicionar chamadas de Hook a ela no futuro. Nesse caso, faz sentido nomeá-la com o prefixo `use`. ```js {3-4} -// ✅ Good: A Hook that will likely use some other Hooks later +// ✅ Bom: um Hook que provavelmente usará outros Hooks posteriormente function useAuth() { - // TODO: Replace with this line when authentication is implemented: + // TODO: Substitua por esta linha quando a autenticação for implementada: // return useContext(Auth); return TEST_USER; } ``` -Then components won't be able to call it conditionally. This will become important when you actually add Hook calls inside. If you don't plan to use Hooks inside it (now or later), don't make it a Hook. +Então, os componentes não poderão chamá-lo condicionalmente. Isso se tornará importante quando você realmente adicionar chamadas de Hook no interior. Se você não planeja usar Hooks dentro dele (agora ou posteriormente), não o transforme em um Hook. -### Custom Hooks let you share stateful logic, not state itself {/*custom-hooks-let-you-share-stateful-logic-not-state-itself*/} +### Hooks personalizados permitem compartilhar lógica com estado, não o próprio estado {/*custom-hooks-let-you-share-stateful-logic-not-state-itself*/} -In the earlier example, when you turned the network on and off, both components updated together. However, it's wrong to think that a single `isOnline` state variable is shared between them. Look at this code: +No exemplo anterior, quando você ligou e desligou a rede, ambos os componentes foram atualizados juntos. No entanto, é incorreto pensar que uma única variável de estado `isOnline` é compartilhada entre eles. Observe este código: ```js {2,7} function StatusBar() { @@ -305,7 +305,7 @@ function SaveButton() { } ``` -It works the same way as before you extracted the duplication: +Ele funciona da mesma forma que antes de extrair a duplicação: ```js {2-5,10-13} function StatusBar() { @@ -325,9 +325,9 @@ function SaveButton() { } ``` -These are two completely independent state variables and Effects! They happened to have the same value at the same time because you synchronized them with the same external value (whether the network is on). +Essas são duas variáveis de estado e efeitos completamente independentes! Elas acabaram tendo o mesmo valor ao mesmo tempo porque foram sincronizadas com o mesmo valor externo (se a rede está ligada ou desligada). -To better illustrate this, we'll need a different example. Consider this `Form` component: +Para ilustrar melhor isso, precisaremos de um exemplo diferente. Considere este componente `Form`: @@ -369,13 +369,13 @@ input { margin-left: 10px; } -There's some repetitive logic for each form field: +Há alguma lógica repetitiva para cada campo do formulário: -1. There's a piece of state (`firstName` and `lastName`). -1. There's a change handler (`handleFirstNameChange` and `handleLastNameChange`). -1. There's a piece of JSX that specifies the `value` and `onChange` attributes for that input. +1. Há uma variável de estado (`firstName` e `lastName`). +2. Há um manipulador de alteração (`handleFirstNameChange` e `handleLastNameChange`). +3. Há uma parte de JSX que especifica os atributos `value` e `onChange` para a entrada. -You can extract the repetitive logic into this `useFormInput` custom Hook: +Você pode extrair a lógica repetitiva para este Hook personalizado `useFormInput`: @@ -428,9 +428,9 @@ input { margin-left: 10px; } -Notice that it only declares *one* state variable called `value`. +Observe que ele declara apenas uma variável de estado chamada `value`. -However, the `Form` component calls `useFormInput` *two times:* +No entanto, o componente `Form` chama `useFormInput` *duas vezes*: ```js function Form() { @@ -439,17 +439,17 @@ function Form() { // ... ``` -This is why it works like declaring two separate state variables! +É por isso que funciona como se estivéssemos declarando duas variáveis de estado separadas! -**Custom Hooks let you share *stateful logic* but not *state itself.* Each call to a Hook is completely independent from every other call to the same Hook.** This is why the two sandboxes above are completely equivalent. If you'd like, scroll back up and compare them. The behavior before and after extracting a custom Hook is identical. +**Os Hooks personalizados permitem compartilhar *lógica com estado* e não *o próprio estado*. Cada chamada a um Hook é completamente independente de qualquer outra chamada ao mesmo Hook.** É por isso que as duas áreas de teste acima são completamente equivalentes. Se desejar, role para cima e compare-as. O comportamento antes e depois de extrair um Hook personalizado é idêntico. -When you need to share the state itself between multiple components, [lift it up and pass it down](/learn/sharing-state-between-components) instead. +Quando você precisa compartilhar o próprio estado entre vários componentes, [eleve-o e passe-o como propriedade](/learn/sharing-state-between-components) em vez disso. -## Passing reactive values between Hooks {/*passing-reactive-values-between-hooks*/} +## Passando valores reativos entre Hooks {/*passing-reactive-values-between-hooks*/} -The code inside your custom Hooks will re-run during every re-render of your component. This is why, like components, custom Hooks [need to be pure.](/learn/keeping-components-pure) Think of custom Hooks' code as part of your component's body! +O código dentro dos seus Hooks personalizados será executado novamente durante cada nova renderização do seu componente. É por isso que, assim como os componentes, os Hooks personalizados [precisam ser puros](/learn/keeping-components-pure). Pense no código dos Hooks personalizados como parte do corpo do seu componente! -Because custom Hooks re-render together with your component, they always receive the latest props and state. To see what this means, consider this chat room example. Change the server URL or the chat room: +Como os Hooks personalizados são renderizados juntamente com o seu componente, eles sempre recebem as props e o estado mais recentes. Para entender o que isso significa, considere este exemplo de sala de bate-papo. Altere a URL do servidor ou a sala de bate-papo: @@ -496,7 +496,7 @@ export default function ChatRoom({ roomId }) { }; const connection = createConnection(options); connection.on('message', (msg) => { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); }); connection.connect(); return () => connection.disconnect(); @@ -516,7 +516,7 @@ export default function ChatRoom({ roomId }) { ```js chat.js export function createConnection({ serverUrl, roomId }) { - // A real implementation would actually connect to the server + // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); } @@ -527,7 +527,7 @@ export function createConnection({ serverUrl, roomId }) { let messageCallback; return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ Conectando a "' + roomId + '" sala em ' + serverUrl + '...'); clearInterval(intervalId); intervalId = setInterval(() => { if (messageCallback) { @@ -542,7 +542,7 @@ export function createConnection({ serverUrl, roomId }) { disconnect() { clearInterval(intervalId); messageCallback = null; - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl + ''); + console.log('❌ Desconectado de "' + roomId + '" sala em ' + serverUrl + ''); }, on(event, callback) { if (messageCallback) { @@ -599,9 +599,9 @@ button { margin-left: 10px; } -When you change `serverUrl` or `roomId`, the Effect ["reacts" to your changes](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) and re-synchronizes. You can tell by the console messages that the chat re-connects every time that you change your Effect's dependencies. +Quando você altera `serverUrl` ou `roomId`, o efeito ["reage" às suas mudanças](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) e ressincroniza. Você pode observar pelas mensagens no console que o chat se reconecta toda vez que você altera as dependências do seu efeito. -Now move the Effect's code into a custom Hook: +Agora mova o código do efeito para um Hook personalizado: ```js {2-13} export function useChatRoom({ serverUrl, roomId }) { @@ -613,14 +613,14 @@ export function useChatRoom({ serverUrl, roomId }) { const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); }); return () => connection.disconnect(); }, [roomId, serverUrl]); } ``` -This lets your `ChatRoom` component call your custom Hook without worrying about how it works inside: +Isso permite que seu componente `ChatRoom` chame o seu Hook personalizado sem se preocupar com o funcionamento interno: ```js {4-7} export default function ChatRoom({ roomId }) { @@ -643,9 +643,9 @@ export default function ChatRoom({ roomId }) { } ``` -This looks much simpler! (But it does the same thing.) +Isso parece muito mais simples! (Mas faz a mesma coisa.) -Notice that the logic *still responds* to prop and state changes. Try editing the server URL or the selected room: +Observe que a lógica *ainda responde* às mudanças nas props e no estado. Experimente editar a URL do servidor ou a sala selecionada: @@ -715,7 +715,7 @@ export function useChatRoom({ serverUrl, roomId }) { const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); }); return () => connection.disconnect(); }, [roomId, serverUrl]); @@ -724,7 +724,7 @@ export function useChatRoom({ serverUrl, roomId }) { ```js chat.js export function createConnection({ serverUrl, roomId }) { - // A real implementation would actually connect to the server + // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); } @@ -735,7 +735,7 @@ export function createConnection({ serverUrl, roomId }) { let messageCallback; return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ Conectando a "' + roomId + '" sala em ' + serverUrl + '...'); clearInterval(intervalId); intervalId = setInterval(() => { if (messageCallback) { @@ -750,7 +750,7 @@ export function createConnection({ serverUrl, roomId }) { disconnect() { clearInterval(intervalId); messageCallback = null; - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl + ''); + console.log('❌ Desconectado de "' + roomId + '" sala em ' + serverUrl + ''); }, on(event, callback) { if (messageCallback) { @@ -807,7 +807,7 @@ button { margin-left: 10px; } -Notice how you're taking the return value of one Hook: +Observe como você está recebendo o valor de retorno de um Hook: ```js {2} export default function ChatRoom({ roomId }) { @@ -820,7 +820,7 @@ export default function ChatRoom({ roomId }) { // ... ``` -and pass it as an input to another Hook: +e passando como entrada para outro Hook: ```js {6} export default function ChatRoom({ roomId }) { @@ -833,17 +833,17 @@ export default function ChatRoom({ roomId }) { // ... ``` -Every time your `ChatRoom` component re-renders, it passes the latest `roomId` and `serverUrl` to your Hook. This is why your Effect re-connects to the chat whenever their values are different after a re-render. (If you ever worked with audio or video processing software, chaining Hooks like this might remind you of chaining visual or audio effects. It's as if the output of `useState` "feeds into" the input of the `useChatRoom`.) +Sempre que o componente `ChatRoom` é renderizado novamente, ele passa as últimas `roomId` e `serverUrl` para o seu Hook. É por isso que o seu efeito se reconecta ao chat sempre que os valores forem diferentes após uma nova renderização. (Se você já trabalhou com software de processamento de áudio ou vídeo, encadear Hooks dessa forma pode lembrar o encadeamento de efeitos visuais ou de áudio. É como se a saída do `useState` "alimentasse" a entrada do `useChatRoom`.) -### Passing event handlers to custom Hooks {/*passing-event-handlers-to-custom-hooks*/} +### Passando manipuladores de eventos para Hooks personalizados {/*passing-event-handlers-to-custom-hooks*/} -This section describes an **experimental API that has not yet been released** in a stable version of React. +Esta seção descreve uma **API experimental que ainda não foi lançada** em uma versão estável do React. -As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook: +Conforme você começa a usar o `useChatRoom` em mais componentes, pode ser desejável permitir que os componentes personalizem seu comportamento. Por exemplo, atualmente, a lógica do que fazer quando uma mensagem chega está codificada diretamente no Hook: ```js {9-11} export function useChatRoom({ serverUrl, roomId }) { @@ -855,14 +855,14 @@ export function useChatRoom({ serverUrl, roomId }) { const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); }); return () => connection.disconnect(); }, [roomId, serverUrl]); } ``` -Let's say you want to move this logic back to your component: +Digamos que você queira mover essa lógica de volta para o seu componente: ```js {7-9} export default function ChatRoom({ roomId }) { @@ -872,13 +872,13 @@ export default function ChatRoom({ roomId }) { roomId: roomId, serverUrl: serverUrl, onReceiveMessage(msg) { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); } }); // ... ``` -To make this work, change your custom Hook to take `onReceiveMessage` as one of its named options: +Para fazer isso funcionar, altere o seu Hook personalizado para receber `onReceiveMessage` como uma das opções nomeadas: ```js {1,10,13} export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { @@ -893,13 +893,13 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { onReceiveMessage(msg); }); return () => connection.disconnect(); - }, [roomId, serverUrl, onReceiveMessage]); // ✅ All dependencies declared + }, [roomId, serverUrl, onReceiveMessage]); // ✅ Todas as dependências declaradas } ``` -This will work, but there's one more improvement you can do when your custom Hook accepts event handlers. +Isso funcionará, mas há mais uma melhoria que você pode fazer quando seu Hook personalizado aceita manipuladores de eventos. -Adding a dependency on `onReceiveMessage` is not ideal because it will cause the chat to re-connect every time the component re-renders. [Wrap this event handler into an Effect Event to remove it from the dependencies:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props) +Adicionar uma dependência em `onReceiveMessage` não é ideal, pois fará com que o chat se reconecte sempre que o componente for renderizado novamente. [Encapsule esse manipulador de eventos em um Event Effect para removê-lo das dependências:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props) ```js {1,4,5,15,18} import { useEffect, useEffectEvent } from 'react'; @@ -919,11 +919,11 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { onMessage(msg); }); return () => connection.disconnect(); - }, [roomId, serverUrl]); // ✅ All dependencies declared + }, [roomId, serverUrl]); // ✅ Todas as dependências declaradas } ``` -Now the chat won't re-connect every time that the `ChatRoom` component re-renders. Here is a fully working demo of passing an event handler to a custom Hook that you can play with: +Agora, o chat não será reconectado toda vez que o componente `ChatRoom` for renderizado novamente. Aqui está um exemplo completo de como passar um manipulador de eventos para um Hook personalizado com o qual você pode brincar: @@ -967,7 +967,7 @@ export default function ChatRoom({ roomId }) { roomId: roomId, serverUrl: serverUrl, onReceiveMessage(msg) { - showNotification('New message: ' + msg); + showNotification('Nova mensagem: ' + msg); } }); @@ -1008,7 +1008,7 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { ```js chat.js export function createConnection({ serverUrl, roomId }) { - // A real implementation would actually connect to the server + // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); } @@ -1019,7 +1019,7 @@ export function createConnection({ serverUrl, roomId }) { let messageCallback; return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ Conectando a "' + roomId + '" sala em ' + serverUrl + '...'); clearInterval(intervalId); intervalId = setInterval(() => { if (messageCallback) { @@ -1034,7 +1034,7 @@ export function createConnection({ serverUrl, roomId }) { disconnect() { clearInterval(intervalId); messageCallback = null; - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl + ''); + console.log('❌ Desconectado de "' + roomId + '" sala em ' + serverUrl + ''); }, on(event, callback) { if (messageCallback) { @@ -1091,20 +1091,20 @@ button { margin-left: 10px; } -Notice how you no longer need to know *how* `useChatRoom` works in order to use it. You could add it to any other component, pass any other options, and it would work the same way. That's the power of custom Hooks. +Observe como agora você não precisa mais saber *como* `useChatRoom` funciona para poder usá-lo. Você poderia adicioná-lo a qualquer outro componente, passar outras opções e ele funcionaria da mesma maneira. Esse é o poder dos Hooks personalizados. -## When to use custom Hooks {/*when-to-use-custom-hooks*/} +## Quando usar Hooks personalizados {/*when-to-use-custom-hooks*/} -You don't need to extract a custom Hook for every little duplicated bit of code. Some duplication is fine. For example, extracting a `useFormInput` Hook to wrap a single `useState` call like earlier is probably unnecessary. +Você não precisa extrair um Hook personalizado para cada pequeno trecho de código duplicado. Alguma duplicação é aceitável. Por exemplo, extrair um Hook `useFormInput` para envolver uma única chamada `useState` como feito anteriormente provavelmente é desnecessário. -However, whenever you write an Effect, consider whether it would be clearer to also wrap it in a custom Hook. [You shouldn't need Effects very often,](/learn/you-might-not-need-an-effect) so if you're writing one, it means that you need to "step outside React" to synchronize with some external system or to do something that React doesn't have a built-in API for. Wrapping it into a custom Hook lets you precisely communicate your intent and how the data flows through it. +No entanto, sempre que você escrever um Efeito, considere se seria mais claro encapsulá-lo também em um Hook personalizado. [Você não deve precisar de Efeitos com muita frequência,](/learn/you-might-not-need-an-effect) então, se você estiver escrevendo um, significa que precisa "sair do mundo React" para sincronizar com algum sistema externo ou fazer algo para o qual o React não tenha uma API embutida. encapsular o Efeito em um Hook personalizado permite que você comunique claramente sua intenção e como os dados fluem por ele. -For example, consider a `ShippingForm` component that displays two dropdowns: one shows the list of cities, and another shows the list of areas in the selected city. You might start with some code that looks like this: +Por exemplo, considere um componente `ShippingForm` que exibe dois dropdowns: um mostra a lista de cidades e outro mostra a lista de áreas na cidade selecionada. Você pode começar com um código que se parece com isso: ```js {3-16,20-35} function ShippingForm({ country }) { const [cities, setCities] = useState(null); - // This Effect fetches cities for a country + // Este efeito busca cidades para um país useEffect(() => { let ignore = false; fetch(`/api/cities?country=${country}`) @@ -1121,7 +1121,7 @@ function ShippingForm({ country }) { const [city, setCity] = useState(null); const [areas, setAreas] = useState(null); - // This Effect fetches areas for the selected city + // Esse efeito busca as áreas para a cidade selecionada. useEffect(() => { if (city) { let ignore = false; @@ -1141,7 +1141,7 @@ function ShippingForm({ country }) { // ... ``` -Although this code is quite repetitive, [it's correct to keep these Effects separate from each other.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) They synchronize two different things, so you shouldn't merge them into one Effect. Instead, you can simplify the `ShippingForm` component above by extracting the common logic between them into your own `useData` Hook: +Embora este código seja bastante repetitivo, [é correto manter esses efeitos separados um do outro.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) Eles sincronizam duas coisas diferentes, portanto, não deve-se mesclá-los em um único efeito. Em vez disso, você pode simplificar o componente `ShippingForm` acima extraindo a lógica comum entre eles para o seu próprio Hook `useData`: ```js {2-18} function useData(url) { @@ -1165,7 +1165,7 @@ function useData(url) { } ``` -Now you can replace both Effects in the `ShippingForm` components with calls to `useData`: +Agora você pode substituir os dois efeitos nos componentes `ShippingForm` por chamadas ao `useData`: ```js {2,4} function ShippingForm({ country }) { @@ -1175,39 +1175,39 @@ function ShippingForm({ country }) { // ... ``` -Extracting a custom Hook makes the data flow explicit. You feed the `url` in and you get the `data` out. By "hiding" your Effect inside `useData`, you also prevent someone working on the `ShippingForm` component from adding [unnecessary dependencies](/learn/removing-effect-dependencies) to it. With time, most of your app's Effects will be in custom Hooks. +Extrair um Hook personalizado torna o fluxo de dados explícito. Você fornece a `url` como entrada e obtém a `data` como saída. Ao "esconder" seu efeito dentro do `useData`, você também impede que alguém que trabalhe no componente `ShippingForm` adicione [dependências desnecessárias](/learn/removing-effect-dependencies) a ele. Com o tempo, a maioria dos efeitos do seu aplicativo estará nos Hooks personalizados. -#### Keep your custom Hooks focused on concrete high-level use cases {/*keep-your-custom-hooks-focused-on-concrete-high-level-use-cases*/} +#### Mantenha seus Hooks personalizados focados em casos de uso concretos de alto nível {/*keep-your-custom-hooks-focused-on-concrete-high-level-use-cases*/} -Start by choosing your custom Hook's name. If you struggle to pick a clear name, it might mean that your Effect is too coupled to the rest of your component's logic, and is not yet ready to be extracted. +Comece escolhendo o nome do seu Hook personalizado. Se você tiver dificuldade em escolher um nome claro, isso pode significar que seu Efeito está muito acoplado à lógica do restante do seu componente e ainda não está pronto para ser extraído. -Ideally, your custom Hook's name should be clear enough that even a person who doesn't write code often could have a good guess about what your custom Hook does, what it takes, and what it returns: +Idealmente, o nome do seu Hook personalizado deve ser claro o suficiente para que até mesmo uma pessoa que não escreve código com frequência possa ter uma boa ideia do que seu Hook personalizado faz, o que ele recebe e o que retorna: * ✅ `useData(url)` * ✅ `useImpressionLog(eventName, extraData)` * ✅ `useChatRoom(options)` -When you synchronize with an external system, your custom Hook name may be more technical and use jargon specific to that system. It's good as long as it would be clear to a person familiar with that system: +Quando você se sincroniza com um sistema externo, o nome do seu Hook personalizado pode ser mais técnico e usar jargões específicos desse sistema. Isso é bom, desde que seja claro para uma pessoa familiarizada com esse sistema: * ✅ `useMediaQuery(query)` * ✅ `useSocket(url)` * ✅ `useIntersectionObserver(ref, options)` -**Keep custom Hooks focused on concrete high-level use cases.** Avoid creating and using custom "lifecycle" Hooks that act as alternatives and convenience wrappers for the `useEffect` API itself: +**Mantenha os Hooks personalizados focados em casos de uso concretos de alto nível.** Evite criar e usar Hooks personalizados de "ciclo de vida" que atuem como alternativas e encapsuladores de conveniência para a própria API `useEffect`: * 🔴 `useMount(fn)` * 🔴 `useEffectOnce(fn)` * 🔴 `useUpdateEffect(fn)` -For example, this `useMount` Hook tries to ensure some code only runs "on mount": +Por exemplo, este Hook `useMount` tenta garantir que determinado código seja executado apenas "no momento da montagem": ```js {4-5,14-15} function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); - // 🔴 Avoid: using custom "lifecycle" Hooks + // 🔴 Evite: usar Hooks personalizados de "ciclo de vida" useMount(() => { const connection = createConnection({ roomId, serverUrl }); connection.connect(); @@ -1217,23 +1217,23 @@ function ChatRoom({ roomId }) { // ... } -// 🔴 Avoid: creating custom "lifecycle" Hooks +// 🔴 Evite: criar Hooks personalizados de "ciclo de vida" function useMount(fn) { useEffect(() => { fn(); - }, []); // 🔴 React Hook useEffect has a missing dependency: 'fn' + }, []); // 🔴 React Hook `useEffect` está com uma dependência faltando: 'fn' } ``` -**Custom "lifecycle" Hooks like `useMount` don't fit well into the React paradigm.** For example, this code example has a mistake (it doesn't "react" to `roomId` or `serverUrl` changes), but the linter won't warn you about it because the linter only checks direct `useEffect` calls. It won't know about your Hook. +**Hooks personalizados de "ciclo de vida", como `useMount`, não se encaixam bem no paradigma do React.** Por exemplo, este exemplo de código contém um erro (ele não "reage" às alterações em `roomId` ou `serverUrl`), mas o linter não irá alertá-lo sobre isso porque o linter verifica apenas chamadas diretas de `useEffect`. Ele não saberá sobre o seu Hook. -If you're writing an Effect, start by using the React API directly: +Se você está escrevendo um efeito, comece usando a API do React diretamente: ```js function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); - // ✅ Good: two raw Effects separated by purpose + // ✅ Bom: dois efeitos separados por finalidade useEffect(() => { const connection = createConnection({ serverUrl, roomId }); @@ -1249,28 +1249,28 @@ function ChatRoom({ roomId }) { } ``` -Then, you can (but don't have to) extract custom Hooks for different high-level use cases: +Em seguida, você pode (mas não é obrigatório) extrair Hooks personalizados para diferentes casos de uso de alto nível: ```js function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); - // ✅ Great: custom Hooks named after their purpose + // ✅ Ótimo: Hooks personalizados nomeados de acordo com sua finalidade useChatRoom({ serverUrl, roomId }); useImpressionLog('visit_chat', { roomId }); // ... } ``` -**A good custom Hook makes the calling code more declarative by constraining what it does.** For example, `useChatRoom(options)` can only connect to the chat room, while `useImpressionLog(eventName, extraData)` can only send an impression log to the analytics. If your custom Hook API doesn't constrain the use cases and is very abstract, in the long run it's likely to introduce more problems than it solves. +**Um bom Hook personalizado torna o código de chamada mais declarativo, restringindo o que ele faz.** Por exemplo, `useChatRoom(options)` pode apenas se conectar à sala de bate-papo, enquanto `useImpressionLog(eventName, extraData)` pode apenas enviar um registro de impressão para a análise. Se a API do seu Hook personalizado não restringir os casos de uso e for muito abstrata, a longo prazo é provável que introduza mais problemas do que resolve. -### Custom Hooks help you migrate to better patterns {/*custom-hooks-help-you-migrate-to-better-patterns*/} +### Hooks personalizados ajudam na migração para padrões melhores {/*custom-hooks-help-you-migrate-to-better-patterns*/} -Effects are an ["escape hatch"](/learn/escape-hatches): you use them when you need to "step outside React" and when there is no better built-in solution for your use case. With time, the React team's goal is to reduce the number of the Effects in your app to the minimum by providing more specific solutions to more specific problems. Wrapping your Effects in custom Hooks makes it easier to upgrade your code when these solutions become available. +Os efeitos são uma ["porta de escape"](/learn/escape-hatches): você os utiliza quando precisa "sair do React" e não há uma solução interna melhor para o seu caso de uso. Com o tempo, o objetivo da equipe do React é reduzir ao mínimo o número de efeitos em seu aplicativo, fornecendo soluções mais específicas para problemas mais específicos. Encapsular seus efeitos em Hooks personalizados facilita a atualização do seu código quando essas soluções estiverem disponíveis. -Let's return to this example: +Vamos voltar a este exemplo: @@ -1279,19 +1279,19 @@ import { useOnlineStatus } from './useOnlineStatus.js'; function StatusBar() { const isOnline = useOnlineStatus(); - return

{isOnline ? '✅ Online' : '❌ Disconnected'}

; + return

{isOnline ? '✅ Conectado' : '❌ Desconectado'}

; } function SaveButton() { const isOnline = useOnlineStatus(); function handleSaveClick() { - console.log('✅ Progress saved'); + console.log('✅ Progresso Salvo'); } return ( ); } @@ -1331,9 +1331,9 @@ export function useOnlineStatus() {
-In the above example, `useOnlineStatus` is implemented with a pair of [`useState`](/reference/react/useState) and [`useEffect`.](/reference/react/useEffect) However, this isn't the best possible solution. There is a number of edge cases it doesn't consider. For example, it assumes that when the component mounts, `isOnline` is already `true`, but this may be wrong if the network already went offline. You can use the browser [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API to check for that, but using it directly would not work on the server for generating the initial HTML. In short, this code could be improved. +No exemplo acima, `useOnlineStatus` é implementado com um par de [`useState`](/reference/react/useState) e [`useEffect`](/reference/react/useEffect). No entanto, essa não é a melhor solução possível. Existem alguns casos específicos que não são considerados. Por exemplo, assume-se que quando o componente é montado, `isOnline` já é `true`, mas isso pode estar errado se a rede já estiver offline. Você pode usar a API do navegador [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) para verificar isso, mas usá-la diretamente não funcionaria no servidor para gerar o HTML inicial. Em resumo, este código pode ser aprimorado. -Luckily, React 18 includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is how your `useOnlineStatus` Hook, rewritten to take advantage of this new API: +Felizmente, o React 18 inclui uma API dedicada chamada [`useSyncExternalStore`](/reference/react/useSyncExternalStore) que cuida de todos esses problemas para você. Aqui está como o seu Hook `useOnlineStatus` pode ser reescrito para aproveitar essa nova API: @@ -1342,19 +1342,19 @@ import { useOnlineStatus } from './useOnlineStatus.js'; function StatusBar() { const isOnline = useOnlineStatus(); - return

{isOnline ? '✅ Online' : '❌ Disconnected'}

; + return

{isOnline ? '✅ Conectado' : '❌ Desconectado'}

; } function SaveButton() { const isOnline = useOnlineStatus(); function handleSaveClick() { - console.log('✅ Progress saved'); + console.log('✅ Progresso Salvo'); } return ( ); } @@ -1384,8 +1384,8 @@ function subscribe(callback) { export function useOnlineStatus() { return useSyncExternalStore( subscribe, - () => navigator.onLine, // How to get the value on the client - () => true // How to get the value on the server + () => navigator.onLine, // Como obter o valor no cliente + () => true // Como obter o valor no servidor ); } @@ -1393,7 +1393,7 @@ export function useOnlineStatus() {
-Notice how **you didn't need to change any of the components** to make this migration: +Observe como **você não precisou alterar nenhum dos componentes** para fazer essa migração: ```js {2,7} function StatusBar() { @@ -1407,22 +1407,22 @@ function SaveButton() { } ``` -This is another reason for why wrapping Effects in custom Hooks is often beneficial: +Este é outro motivo pelo qual envolver efeitos em Hooks personalizados frequentemente é benéfico: -1. You make the data flow to and from your Effects very explicit. -2. You let your components focus on the intent rather than on the exact implementation of your Effects. -3. When React adds new features, you can remove those Effects without changing any of your components. +1. Você torna o fluxo de dados de ida e volta dos seus efeitos muito explícito. +2. Você permite que seus componentes se concentrem na intenção em vez de na implementação exata dos seus efeitos. +3. Quando o React adiciona novos recursos, você pode remover esses efeitos sem precisar alterar nenhum dos seus componentes. -Similar to a [design system,](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969) you might find it helpful to start extracting common idioms from your app's components into custom Hooks. This will keep your components' code focused on the intent, and let you avoid writing raw Effects very often. Many excellent custom Hooks are maintained by the React community. +Similar a um [sistema de design](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969), você pode achar útil começar a extrair idiomatismos comuns dos componentes do seu aplicativo em Hooks personalizados. Isso manterá o código dos seus componentes focado na intenção e permitirá evitar escrever efeitos brutos com frequência. Muitos Hooks personalizados excelentes são mantidos pela comunidade do React. -#### Will React provide any built-in solution for data fetching? {/*will-react-provide-any-built-in-solution-for-data-fetching*/} +#### O React fornecerá alguma solução interna para busca de dados? {/*will-react-provide-any-built-in-solution-for-data-fetching*/} -We're still working out the details, but we expect that in the future, you'll write data fetching like this: +Ainda estamos trabalhando nos detalhes, mas esperamos que no futuro você escreva a busca de dados da seguinte forma: ```js {1,4,6} -import { use } from 'react'; // Not available yet! +import { use } from 'react'; // Não disponível ainda! function ShippingForm({ country }) { const cities = use(fetch(`/api/cities?country=${country}`)); @@ -1431,13 +1431,13 @@ function ShippingForm({ country }) { // ... ``` -If you use custom Hooks like `useData` above in your app, it will require fewer changes to migrate to the eventually recommended approach than if you write raw Effects in every component manually. However, the old approach will still work fine, so if you feel happy writing raw Effects, you can continue to do that. +Se você usar Hooks personalizados como `useData` mencionado acima em seu aplicativo, será necessário fazer menos alterações para migrar para a abordagem eventualmente recomendada do que se você escrever efeitos brutos em cada componente manualmente. No entanto, a abordagem antiga ainda funcionará bem, então, se você se sentir confortável escrevendo efeitos brutos, pode continuar fazendo isso. -### There is more than one way to do it {/*there-is-more-than-one-way-to-do-it*/} +### Há mais de uma maneira de fazer isso {/*there-is-more-than-one-way-to-do-it*/} -Let's say you want to implement a fade-in animation *from scratch* using the browser [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) API. You might start with an Effect that sets up an animation loop. During each frame of the animation, you could change the opacity of the DOM node you [hold in a ref](/learn/manipulating-the-dom-with-refs) until it reaches `1`. Your code might start like this: +Vamos supor que você queira implementar uma animação de fade-in *do zero* usando a API do navegador [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). Você pode começar com um efeito que configura um loop de animação. Durante cada quadro da animação, você poderia alterar a opacidade do nó do DOM que você [mantém em uma referência (ref)](/learn/manipulating-the-dom-with-refs) até que ela atinja o valor `1`. Seu código pode começar assim: @@ -1459,7 +1459,7 @@ function Welcome() { const progress = Math.min(timePassed / duration, 1); onProgress(progress); if (progress < 1) { - // We still have more frames to paint + // Ainda temos mais quadros para renderizar frameId = requestAnimationFrame(onFrame); } } @@ -1520,7 +1520,7 @@ html, body { min-height: 300px; } -To make the component more readable, you might extract the logic into a `useFadeIn` custom Hook: +Para tornar o componente mais legível, você pode extrair a lógica para um Hook personalizado `useFadeIn`: @@ -1569,7 +1569,7 @@ export function useFadeIn(ref, duration) { const progress = Math.min(timePassed / duration, 1); onProgress(progress); if (progress < 1) { - // We still have more frames to paint + // Ainda temos mais quadros para renderizar frameId = requestAnimationFrame(onFrame); } } @@ -1611,7 +1611,7 @@ html, body { min-height: 300px; } -You could keep the `useFadeIn` code as is, but you could also refactor it more. For example, you could extract the logic for setting up the animation loop out of `useFadeIn` into a custom `useAnimationLoop` Hook: +Você pode manter o código do `useFadeIn` como está, mas também pode refatorá-lo ainda mais. Por exemplo, você pode extrair a lógica para configurar o loop de animação do `useFadeIn` para um Hook personalizado `useAnimationLoop`: @@ -1715,7 +1715,7 @@ html, body { min-height: 300px; } -However, you didn't *have to* do that. As with regular functions, ultimately you decide where to draw the boundaries between different parts of your code. You could also take a very different approach. Instead of keeping the logic in the Effect, you could move most of the imperative logic inside a JavaScript [class:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) +No entanto, você *não precisou* fazer isso. Assim como com funções regulares, você decide em última instância onde definir os limites entre diferentes partes do seu código. Você também pode adotar uma abordagem muito diferente. Em vez de manter a lógica no efeito, você poderia mover a maior parte da lógica imperativa para uma [classe](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) JavaScript: @@ -1782,7 +1782,7 @@ export class FadeInAnimation { if (progress === 1) { this.stop(); } else { - // We still have more frames to paint + // Ainda temos mais quadros para renderizar this.frameId = requestAnimationFrame(() => this.onFrame()); } } @@ -1813,9 +1813,9 @@ html, body { min-height: 300px; } -Effects let you connect React to external systems. The more coordination between Effects is needed (for example, to chain multiple animations), the more it makes sense to extract that logic out of Effects and Hooks *completely* like in the sandbox above. Then, the code you extracted *becomes* the "external system". This lets your Effects stay simple because they only need to send messages to the system you've moved outside React. +Os efeitos permitem conectar o React a sistemas externos. Quanto mais coordenação entre efeitos for necessária (por exemplo, para encadear várias animações), mais faz sentido extrair essa lógica *completamente* dos efeitos e hooks, como no exemplo do código anterior. Em seguida, o código que você extraiu se torna *o sistema externo*. Isso permite que seus efeitos permaneçam simples, pois eles só precisam enviar mensagens para o sistema que você moveu para fora do React. -The examples above assume that the fade-in logic needs to be written in JavaScript. However, this particular fade-in animation is both simpler and much more efficient to implement with a plain [CSS Animation:](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) +Os exemplos acima pressupõem que a lógica do fade-in precisa ser escrita em JavaScript. No entanto, essa animação específica de fade-in é mais simples e muito mais eficiente de ser implementada com uma simples [Animação CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations). @@ -1870,27 +1870,27 @@ html, body { min-height: 300px; } -Sometimes, you don't even need a Hook! +Às vezes, você nem precisa de um Hook! -- Custom Hooks let you share logic between components. -- Custom Hooks must be named starting with `use` followed by a capital letter. -- Custom Hooks only share stateful logic, not state itself. -- You can pass reactive values from one Hook to another, and they stay up-to-date. -- All Hooks re-run every time your component re-renders. -- The code of your custom Hooks should be pure, like your component's code. -- Wrap event handlers received by custom Hooks into Effect Events. -- Don't create custom Hooks like `useMount`. Keep their purpose specific. -- It's up to you how and where to choose the boundaries of your code. +- Hooks personalizados permitem compartilhar lógica entre componentes. +- Hooks personalizados devem ser nomeados começando com `use`, seguido por uma letra maiúscula. +- Hooks personalizados compartilham apenas a lógica relacionada ao estado, não o estado em si. +- É possível passar valores reativos de um Hook para outro, e eles se mantêm atualizados. +- Todos os Hooks são executados novamente sempre que o componente é renderizado novamente. +- O código dos seus Hooks personalizados deve ser puro, assim como o código do seu componente. +- Encapsular manipuladores de eventos recebidos por Hooks personalizados em Effects de Evento. +- Não crie Hooks personalizados como `useMount`. Mantenha o propósito deles específico. +- Cabe a você escolher como e onde definir os limites do seu código. -#### Extract a `useCounter` Hook {/*extract-a-usecounter-hook*/} +#### Extrair um Hook `useCounter` {/*extract-a-usecounter-hook*/} -This component uses a state variable and an Effect to display a number that increments every second. Extract this logic into a custom Hook called `useCounter`. Your goal is to make the `Counter` component implementation look exactly like this: +Este componente usa uma variável de estado e um efeito para exibir um número que incrementa a cada segundo. Extraia essa lógica para um Hook personalizado chamado `useCounter`. Seu objetivo é fazer com que a implementação do componente `Counter` fique exatamente assim: ```js export default function Counter() { @@ -1899,7 +1899,7 @@ export default function Counter() { } ``` -You'll need to write your custom Hook in `useCounter.js` and import it into the `Counter.js` file. +Você precisará escrever seu Hook personalizado no arquivo `useCounter.js` e importá-lo no arquivo `Counter.js`. @@ -1919,14 +1919,14 @@ export default function Counter() { ``` ```js useCounter.js -// Write your custom Hook in this file! +// Escreva seu Hook personalizado neste arquivo! ``` -Your code should look like this: +Seu código deve se parecer com isto: @@ -1956,13 +1956,13 @@ export function useCounter() { -Notice that `App.js` doesn't need to import `useState` or `useEffect` anymore. +Observe que `App.js` não precisa mais importar `useState` ou `useEffect`. -#### Make the counter delay configurable {/*make-the-counter-delay-configurable*/} +#### Torne o atraso do contador configurável {/*make-the-counter-delay-configurable*/} -In this example, there is a `delay` state variable controlled by a slider, but its value is not used. Pass the `delay` value to your custom `useCounter` Hook, and change the `useCounter` Hook to use the passed `delay` instead of hardcoding `1000` ms. +Neste exemplo, há uma variável de estado `delay` controlada por um slider, mas seu valor não está sendo utilizado. Passe o valor de `delay` para o seu Hook personalizado `useCounter` e altere o Hook `useCounter` para usar o `delay` passado em vez de codificar `1000` ms. @@ -2012,7 +2012,7 @@ export function useCounter() { -Pass the `delay` to your Hook with `useCounter(delay)`. Then, inside the Hook, use `delay` instead of the hardcoded `1000` value. You'll need to add `delay` to your Effect's dependencies. This ensures that a change in `delay` will reset the interval. +Passe o `delay` para o seu Hook com `useCounter(delay)`. Em seguida, dentro do Hook, use `delay` em vez do valor codificado `1000`. Você precisará adicionar `delay` às dependências do seu efeito. Isso garante que uma alteração no `delay` redefina o intervalo. @@ -2062,9 +2062,9 @@ export function useCounter(delay) { -#### Extract `useInterval` out of `useCounter` {/*extract-useinterval-out-of-usecounter*/} +#### Extrair `useInterval` fora do `useCounter` {/*extract-useinterval-out-of-usecounter*/} -Currently, your `useCounter` Hook does two things. It sets up an interval, and it also increments a state variable on every interval tick. Split out the logic that sets up the interval into a separate Hook called `useInterval`. It should take two arguments: the `onTick` callback, and the `delay`. After this change, your `useCounter` implementation should look like this: +Atualmente, seu Hook `useCounter` faz duas coisas. Ele configura um intervalo e também incrementa uma variável de estado a cada intervalo. Separe a lógica que configura o intervalo em um Hook separado chamado `useInterval`. Ele deve receber dois argumentos: o callback `onTick` e o `delay`. Após essa alteração, a implementação do seu `useCounter` deve ficar assim: ```js export function useCounter(delay) { @@ -2076,7 +2076,7 @@ export function useCounter(delay) { } ``` -Write `useInterval` in the `useInterval.js` file and import it into the `useCounter.js` file. +Escreva `useInterval` no arquivo `useInterval.js` e importe-o no arquivo `useCounter.js`. @@ -2106,14 +2106,14 @@ export function useCounter(delay) { ``` ```js useInterval.js -// Write your Hook here! +// Escreva seu Hook aqui! ``` -The logic inside `useInterval` should set up and clear the interval. It doesn't need to do anything else. +A lógica dentro do `useInterval` deve configurar e limpar o intervalo. Não precisa fazer mais nada. @@ -2152,36 +2152,36 @@ export function useInterval(onTick, delay) { -Note that there is a bit of a problem with this solution, which you'll solve in the next challenge. +Observe que há um pequeno problema com essa solução, que você resolverá no próximo desafio. -#### Fix a resetting interval {/*fix-a-resetting-interval*/} +#### Corrigir um intervalo que é resetado {/*fix-a-resetting-interval*/} -In this example, there are *two* separate intervals. +No exemplo dado, existem *dois* intervalos separados. -The `App` component calls `useCounter`, which calls `useInterval` to update the counter every second. But the `App` component *also* calls `useInterval` to randomly update the page background color every two seconds. +O componente `App` chama `useCounter`, que por sua vez chama `useInterval` para atualizar o contador a cada segundo. Mas o componente `App` *também* chama `useInterval` para atualizar aleatoriamente a cor de fundo da página a cada dois segundos. -For some reason, the callback that updates the page background never runs. Add some logs inside `useInterval`: +Por algum motivo, o callback que atualiza o fundo da página nunca é executado. Adicione alguns logs dentro do `useInterval`: ```js {2,5} useEffect(() => { - console.log('✅ Setting up an interval with delay ', delay) + console.log('✅ Configurando um intervalo com atraso ', delay) const id = setInterval(onTick, delay); return () => { - console.log('❌ Clearing an interval with delay ', delay) + console.log('❌ Limpando um intervalo com atraso ', delay) clearInterval(id); }; }, [onTick, delay]); ``` -Do the logs match what you expect to happen? If some of your Effects seem to re-synchronize unnecessarily, can you guess which dependency is causing that to happen? Is there some way to [remove that dependency](/learn/removing-effect-dependencies) from your Effect? +Os logs correspondem ao que você espera que aconteça? Se alguns de seus Effects parecem ser ressincronizados desnecessariamente, você consegue adivinhar qual dependência está causando isso? Existe alguma maneira de [remover essa dependência](/learn/removing-effect-dependencies) do seu efeito? -After you fix the issue, you should expect the page background to update every two seconds. +Depois de corrigir o problema, você deve esperar que o fundo da página seja atualizado a cada dois segundos. -It looks like your `useInterval` Hook accepts an event listener as an argument. Can you think of some way to wrap that event listener so that it doesn't need to be a dependency of your Effect? +Parece que o seu Hook `useInterval` aceita um ouvinte de evento como argumento. Você consegue pensar em alguma maneira de encapsular esse ouvinte de evento para que ele não precise ser uma dependência do seu Effect? @@ -2250,11 +2250,11 @@ export function useInterval(onTick, delay) { -Inside `useInterval`, wrap the tick callback into an Effect Event, as you did [earlier on this page.](/learn/reusing-logic-with-custom-hooks#passing-event-handlers-to-custom-hooks) +Dentro do `useInterval`, encapsule o callback do tick em um Evento de Efeito, como você fez [anteriormente nesta página.](/learn/reusing-logic-with-custom-hooks#passing-event-handlers-to-custom-hooks) -This will allow you to omit `onTick` from dependencies of your Effect. The Effect won't re-synchronize on every re-render of the component, so the page background color change interval won't get reset every second before it has a chance to fire. +Isso permitirá que você omita `onTick` das dependências do seu Effect. O Effect não será ressincronizado a cada re-renderização do componente, portanto, o intervalo de alteração da cor de fundo da página não será redefinido a cada segundo antes de ter a chance de disparar. -With this change, both intervals work as expected and don't interfere with each other: +Com essa alteração, ambos os intervalos funcionam como esperado e não interferem um no outro: @@ -2321,21 +2321,21 @@ export function useInterval(callback, delay) { -#### Implement a staggering movement {/*implement-a-staggering-movement*/} +#### Implemente um movimento impressionante {/*implement-a-staggering-movement*/} -In this example, the `usePointerPosition()` Hook tracks the current pointer position. Try moving your cursor or your finger over the preview area and see the red dot follow your movement. Its position is saved in the `pos1` variable. +Neste exemplo, o Hook `usePointerPosition()` rastreia a posição atual do ponteiro. Tente mover o cursor do mouse ou o dedo sobre a área de visualização e observe o ponto vermelho seguir o seu movimento. Sua posição é armazenada na variável `pos1`. -In fact, there are five (!) different red dots being rendered. You don't see them because currently they all appear at the same position. This is what you need to fix. What you want to implement instead is a "staggered" movement: each dot should "follow" the previous dot's path. For example, if you quickly move your cursor, the first dot should follow it immediately, the second dot should follow the first dot with a small delay, the third dot should follow the second dot, and so on. +Na verdade, existem cinco (!) pontos vermelhos diferentes sendo renderizados. Você não os vê porque atualmente todos aparecem na mesma posição. Isso é o que você precisa corrigir. Em vez disso, você deseja implementar um movimento "escalado": cada ponto deve "seguir" o caminho do ponto anterior. Por exemplo, se você mover rapidamente o cursor, o primeiro ponto deve segui-lo imediatamente, o segundo ponto deve seguir o primeiro ponto com um pequeno atraso, o terceiro ponto deve seguir o segundo ponto e assim por diante. -You need to implement the `useDelayedValue` custom Hook. Its current implementation returns the `value` provided to it. Instead, you want to return the value back from `delay` milliseconds ago. You might need some state and an Effect to do this. +Você precisa implementar o Hook personalizado `useDelayedValue`. Sua implementação atual retorna o `value` fornecido a ele. Em vez disso, você deseja retornar o valor de volta de `delay` milissegundos atrás. Você pode precisar de algum estado e um Effect para fazer isso. -After you implement `useDelayedValue`, you should see the dots move following one another. +Após você implementar o `useDelayedValue`, você deverá ver os pontos se movendo um após o outro. -You'll need to store the `delayedValue` as a state variable inside your custom Hook. When the `value` changes, you'll want to run an Effect. This Effect should update `delayedValue` after the `delay`. You might find it helpful to call `setTimeout`. +Você precisará armazenar o `delayedValue` como uma variável de estado dentro do seu Hook personalizado. Quando o `value` mudar, você desejará executar um efeito. Este efeito deve atualizar o `delayedValue` após o `delay`. Pode ser útil usar `setTimeout` para isso. -Does this Effect need cleanup? Why or why not? +Este efeito precisa de limpeza? Por quê ou por que não? @@ -2345,7 +2345,7 @@ Does this Effect need cleanup? Why or why not? import { usePointerPosition } from './usePointerPosition.js'; function useDelayedValue(value, delay) { - // TODO: Implement this Hook + // TODO: Implemente este Hook return value; } @@ -2408,7 +2408,7 @@ body { min-height: 300px; } -Here is a working version. You keep the `delayedValue` as a state variable. When `value` updates, your Effect schedules a timeout to update the `delayedValue`. This is why the `delayedValue` always "lags behind" the actual `value`. +Aqui está uma versão funcional. Você mantém o `delayedValue` como uma variável de estado. Quando o `value` é atualizado, seu efeito agenda um timeout para atualizar o `delayedValue`. É por isso que o `delayedValue` sempre fica "atrasado" em relação ao valor real. @@ -2485,7 +2485,7 @@ body { min-height: 300px; } -Note that this Effect *does not* need cleanup. If you called `clearTimeout` in the cleanup function, then each time the `value` changes, it would reset the already scheduled timeout. To keep the movement continuous, you want all the timeouts to fire. +Observe que este efeito *não precisa* de uma limpeza. Se você chamasse `clearTimeout` na função de limpeza, cada vez que o `value` mudasse, ele redefiniria o timeout já agendado. Para manter o movimento contínuo, você deseja que todos os timeouts sejam disparados. From 2cf1693d27f56d600312bdc5064d407bfbe418dc Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Tue, 23 May 2023 15:43:34 -0300 Subject: [PATCH 14/67] translate Reusing logic with custom hooks to pt-br --- src/content/learn/reusing-logic-with-custom-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 6cef0dba7..359ecf502 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -1,5 +1,5 @@ --- -title: 'Reusing Logic with Custom Hooks' +title: 'Reutilizando lógica com Hooks personalizados' --- From 8a2c048032f6f5bcbac93b8b6e4574a36ead81af Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Tue, 23 May 2023 15:47:19 -0300 Subject: [PATCH 15/67] translate Reusing logic with custom hooks to pt-br --- src/content/learn/reusing-logic-with-custom-hooks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 359ecf502..2b314b179 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -1097,7 +1097,7 @@ Observe como agora você não precisa mais saber *como* `useChatRoom` funciona p Você não precisa extrair um Hook personalizado para cada pequeno trecho de código duplicado. Alguma duplicação é aceitável. Por exemplo, extrair um Hook `useFormInput` para envolver uma única chamada `useState` como feito anteriormente provavelmente é desnecessário. -No entanto, sempre que você escrever um Efeito, considere se seria mais claro encapsulá-lo também em um Hook personalizado. [Você não deve precisar de Efeitos com muita frequência,](/learn/you-might-not-need-an-effect) então, se você estiver escrevendo um, significa que precisa "sair do mundo React" para sincronizar com algum sistema externo ou fazer algo para o qual o React não tenha uma API embutida. encapsular o Efeito em um Hook personalizado permite que você comunique claramente sua intenção e como os dados fluem por ele. +No entanto, sempre que você escrever um Efeito, considere se seria mais claro encapsulá-lo também em um Hook personalizado. [Você não deve precisar de efeitos com muita frequência,](/learn/you-might-not-need-an-effect) então, se você estiver escrevendo um, significa que precisa "sair do mundo React" para sincronizar com algum sistema externo ou fazer algo para o qual o React não tenha uma API embutida. encapsular o Efeito em um Hook personalizado permite que você comunique claramente sua intenção e como os dados fluem por ele. Por exemplo, considere um componente `ShippingForm` que exibe dois dropdowns: um mostra a lista de cidades e outro mostra a lista de áreas na cidade selecionada. Você pode começar com um código que se parece com isso: @@ -1880,7 +1880,7 @@ html, body { min-height: 300px; } - É possível passar valores reativos de um Hook para outro, e eles se mantêm atualizados. - Todos os Hooks são executados novamente sempre que o componente é renderizado novamente. - O código dos seus Hooks personalizados deve ser puro, assim como o código do seu componente. -- Encapsular manipuladores de eventos recebidos por Hooks personalizados em Effects de Evento. +- Encapsular manipuladores de eventos recebidos por Hooks personalizados em efeitos de Evento. - Não crie Hooks personalizados como `useMount`. Mantenha o propósito deles específico. - Cabe a você escolher como e onde definir os limites do seu código. @@ -2175,7 +2175,7 @@ Por algum motivo, o callback que atualiza o fundo da página nunca é executado. }, [onTick, delay]); ``` -Os logs correspondem ao que você espera que aconteça? Se alguns de seus Effects parecem ser ressincronizados desnecessariamente, você consegue adivinhar qual dependência está causando isso? Existe alguma maneira de [remover essa dependência](/learn/removing-effect-dependencies) do seu efeito? +Os logs correspondem ao que você espera que aconteça? Se alguns de seus efeitos parecem ser ressincronizados desnecessariamente, você consegue adivinhar qual dependência está causando isso? Existe alguma maneira de [remover essa dependência](/learn/removing-effect-dependencies) do seu efeito? Depois de corrigir o problema, você deve esperar que o fundo da página seja atualizado a cada dois segundos. From e429bbf2ea88b4ecd52fdec394f881f79a9ac38c Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Tue, 23 May 2023 15:57:05 -0300 Subject: [PATCH 16/67] translate Reusing logic with custom hooks to pt-br --- src/content/learn/reusing-logic-with-custom-hooks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 2b314b179..9ec6d6ed4 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -228,7 +228,7 @@ Essa convenção garante que você sempre possa olhar para um componente e saber -Se o seu linter estiver [configurado para o React,](/learn/editor-setup#linting) ele irá impor essa convenção de nomenclatura. Role para cima até a área de sandbox acima e renomeie `useOnlineStatus` para `getOnlineStatus`. Observe que o linter não permitirá mais que você chame `useState` ou `useEffect` dentro dele. Apenas Hooks e componentes podem chamar outros Hooks! +Se o seu linter estiver [configurado para o React,](/learn/editor-setup#linting) ele irá impor essa convenção de nomenclatura. Role para cima até o sandbox e renomeie `useOnlineStatus` para `getOnlineStatus`. Observe que o linter não permitirá mais que você chame `useState` ou `useEffect` dentro dele. Apenas Hooks e componentes podem chamar outros Hooks! @@ -441,7 +441,7 @@ function Form() { É por isso que funciona como se estivéssemos declarando duas variáveis de estado separadas! -**Os Hooks personalizados permitem compartilhar *lógica com estado* e não *o próprio estado*. Cada chamada a um Hook é completamente independente de qualquer outra chamada ao mesmo Hook.** É por isso que as duas áreas de teste acima são completamente equivalentes. Se desejar, role para cima e compare-as. O comportamento antes e depois de extrair um Hook personalizado é idêntico. +**Os Hooks personalizados permitem compartilhar *lógica com estado* e não *o próprio estado*. Cada chamada a um Hook é completamente independente de qualquer outra chamada ao mesmo Hook.** É por isso que as duas sandboxes acima são completamente equivalentes. Se desejar, role para cima e compare-as. O comportamento antes e depois de extrair um Hook personalizado é idêntico. Quando você precisa compartilhar o próprio estado entre vários componentes, [eleve-o e passe-o como propriedade](/learn/sharing-state-between-components) em vez disso. @@ -1813,7 +1813,7 @@ html, body { min-height: 300px; } -Os efeitos permitem conectar o React a sistemas externos. Quanto mais coordenação entre efeitos for necessária (por exemplo, para encadear várias animações), mais faz sentido extrair essa lógica *completamente* dos efeitos e hooks, como no exemplo do código anterior. Em seguida, o código que você extraiu se torna *o sistema externo*. Isso permite que seus efeitos permaneçam simples, pois eles só precisam enviar mensagens para o sistema que você moveu para fora do React. +Os efeitos permitem conectar o React a sistemas externos. Quanto mais coordenação entre efeitos for necessária (por exemplo, para encadear várias animações), mais faz sentido extrair essa lógica *completamente* dos efeitos e hooks, como no sandbox anterior. Em seguida, o código que você extraiu se torna *o sistema externo*. Isso permite que seus efeitos permaneçam simples, pois eles só precisam enviar mensagens para o sistema que você moveu para fora do React. Os exemplos acima pressupõem que a lógica do fade-in precisa ser escrita em JavaScript. No entanto, essa animação específica de fade-in é mais simples e muito mais eficiente de ser implementada com uma simples [Animação CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations). From 3364c93feb358a7d1ac2e8d8b0468c3e32214062 Mon Sep 17 00:00:00 2001 From: Tunzeki Date: Wed, 24 May 2023 00:04:02 +0100 Subject: [PATCH 17/67] Fix typo: change "intermedinate" to "indeterminate" (#6062) --- src/content/reference/react-dom/components/progress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/components/progress.md b/src/content/reference/react-dom/components/progress.md index fd6c96a1e..b783a102d 100644 --- a/src/content/reference/react-dom/components/progress.md +++ b/src/content/reference/react-dom/components/progress.md @@ -35,7 +35,7 @@ To display a progress indicator, render the [built-in browser ``](http Additionally, `` supports these props: * [`max`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#attr-max): A number. Specifies the maximum `value`. Defaults to `1`. -* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#attr-value): A number between `0` and `max`, or `null` for intermedinate progress. Specifies how much was done. +* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#attr-value): A number between `0` and `max`, or `null` for indeterminate progress. Specifies how much was done. --- From 5cb547a05c0d6d947c12fb5610f55e763e07ac6f Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Wed, 24 May 2023 08:24:58 -0300 Subject: [PATCH 18/67] translate Reusing logic with custom hooks to pt-br --- .../learn/reusing-logic-with-custom-hooks.md | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 9ec6d6ed4..b8b8fc12f 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -349,14 +349,14 @@ export default function Form() { return ( <> -

Good morning, {firstName} {lastName}.

+

Bom dia, {firstName} {lastName}.

); } @@ -389,14 +389,14 @@ export default function Form() { return ( <> -

Good morning, {firstNameProps.value} {lastNameProps.value}.

+

Bom dia, {firstNameProps.value} {lastNameProps.value}.

); } @@ -458,18 +458,18 @@ import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('geral'); return ( <>
@@ -505,10 +505,10 @@ export default function ChatRoom({ roomId }) { return ( <> -

Welcome to the {roomId} room!

+

Bem vindo(a) à sala {roomId}

); } @@ -518,10 +518,10 @@ export default function ChatRoom({ roomId }) { export function createConnection({ serverUrl, roomId }) { // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { - throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); + throw Error('Espera-se que serverUrl seja uma string. Recebido: ' + serverUrl); } if (typeof roomId !== 'string') { - throw Error('Expected roomId to be a string. Received: ' + roomId); + throw Error('Espera-se que roomId seja uma string. Recebido: ' + roomId); } let intervalId; let messageCallback; @@ -546,10 +546,10 @@ export function createConnection({ serverUrl, roomId }) { }, on(event, callback) { if (messageCallback) { - throw Error('Cannot add the handler twice.'); + throw Error('Não é possível adicionar o manipulador duas vezes.'); } if (event !== 'message') { - throw Error('Only "message" event is supported.'); + throw Error('Apenas o evento "message" é suportado.'); } messageCallback = callback; }, @@ -634,10 +634,10 @@ export default function ChatRoom({ roomId }) { return ( <> -

Welcome to the {roomId} room!

+

Bem vindo(a) à sala {roomId}

); } @@ -654,18 +654,18 @@ import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('geral'); return ( <>
@@ -692,10 +692,10 @@ export default function ChatRoom({ roomId }) { return ( <> -

Welcome to the {roomId} room!

+

Bem vindo(a) à sala {roomId}

); } @@ -726,10 +726,10 @@ export function useChatRoom({ serverUrl, roomId }) { export function createConnection({ serverUrl, roomId }) { // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { - throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); + throw Error('Espera-se que serverUrl seja uma string. Recebido: ' + serverUrl); } if (typeof roomId !== 'string') { - throw Error('Expected roomId to be a string. Received: ' + roomId); + throw Error('Espera-se que roomId seja uma string. Recebido: ' + roomId); } let intervalId; let messageCallback; @@ -754,10 +754,10 @@ export function createConnection({ serverUrl, roomId }) { }, on(event, callback) { if (messageCallback) { - throw Error('Cannot add the handler twice.'); + throw Error('Não é possível adicionar o manipulador duas vezes.'); } if (event !== 'message') { - throw Error('Only "message" event is supported.'); + throw Error('Apenas o evento "message" é suportado.'); } messageCallback = callback; }, @@ -932,18 +932,18 @@ import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('geral'); return ( <>
@@ -974,10 +974,10 @@ export default function ChatRoom({ roomId }) { return ( <> -

Welcome to the {roomId} room!

+

Bem vindo(a) à sala {roomId}

); } @@ -1010,10 +1010,10 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { export function createConnection({ serverUrl, roomId }) { // Uma implementação real conectaria de fato ao servidor if (typeof serverUrl !== 'string') { - throw Error('Expected serverUrl to be a string. Received: ' + serverUrl); + throw Error('Espera-se que serverUrl seja uma string. Recebido: ' + serverUrl); } if (typeof roomId !== 'string') { - throw Error('Expected roomId to be a string. Received: ' + roomId); + throw Error('Espera-se que roomId seja uma string. Recebido: ' + roomId); } let intervalId; let messageCallback; @@ -1038,10 +1038,10 @@ export function createConnection({ serverUrl, roomId }) { }, on(event, callback) { if (messageCallback) { - throw Error('Cannot add the handler twice.'); + throw Error('Não é possível adicionar o manipulador duas vezes.'); } if (event !== 'message') { - throw Error('Only "message" event is supported.'); + throw Error('Apenas o evento "message" é suportado.'); } messageCallback = callback; }, @@ -1486,7 +1486,7 @@ function Welcome() { return (

- Welcome + Bem vindo(a)

); } @@ -1496,7 +1496,7 @@ export default function App() { return ( <>
{show && } @@ -1535,7 +1535,7 @@ function Welcome() { return (

- Welcome + Bem vindo(a)

); } @@ -1545,7 +1545,7 @@ export default function App() { return ( <>
{show && } @@ -1626,7 +1626,7 @@ function Welcome() { return (

- Welcome + Bem vindo(a)

); } @@ -1636,7 +1636,7 @@ export default function App() { return ( <>
{show && } @@ -1730,7 +1730,7 @@ function Welcome() { return (

- Welcome + Bem vindo(a)

); } @@ -1740,7 +1740,7 @@ export default function App() { return ( <>
{show && } @@ -1826,7 +1826,7 @@ import './welcome.css'; function Welcome() { return (

- Welcome + Bem vindo(a)

); } @@ -1836,7 +1836,7 @@ export default function App() { return ( <>
{show && } @@ -1895,7 +1895,7 @@ Este componente usa uma variável de estado e um efeito para exibir um número q ```js export default function Counter() { const count = useCounter(); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` @@ -1914,7 +1914,7 @@ export default function Counter() { }, 1000); return () => clearInterval(id); }, []); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` @@ -1935,7 +1935,7 @@ import { useCounter } from './useCounter.js'; export default function Counter() { const count = useCounter(); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` @@ -1976,7 +1976,7 @@ export default function Counter() { return ( <>

; + return

Segundos que se passaram: {count}

; } ``` @@ -2122,7 +2122,7 @@ import { useCounter } from './useCounter.js'; export default function Counter() { const count = useCounter(1000); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` @@ -2215,7 +2215,7 @@ export default function Counter() { document.body.style.backgroundColor = randomColor; }, 2000); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` @@ -2287,7 +2287,7 @@ export default function Counter() { document.body.style.backgroundColor = randomColor; }, 2000); - return

Seconds passed: {count}

; + return

Segundos que se passaram: {count}

; } ``` From fc1017952e07e3a0724c7ba8ec38718ba6ab6983 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Ribeiro Dias Date: Wed, 24 May 2023 10:44:32 -0300 Subject: [PATCH 19/67] translate Reusing logic with custom hooks to pt-br --- src/content/learn/reusing-logic-with-custom-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index b8b8fc12f..9df55070d 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -4,7 +4,7 @@ title: 'Reutilizando lógica com Hooks personalizados' -O React vem com vários Hooks embutidos como `useState`, `useContext`, and `useEffect`. Às vezes, você desejará que houvesse um Hook para algum propósito mais específico: Por exemplo, para buscar dados, para acompanhar se o usuário está online, ou para se conectar a uma sala de bate-papo. Você pode não encontrar esses Hooks no React, mas pode criar seus próprios Hooks para as necessidades do seu aplicativo +O React vem com vários Hooks embutidos como `useState`, `useContext`, e `useEffect`. Às vezes, você desejará que houvesse um Hook para algum propósito mais específico: Por exemplo, para buscar dados, para acompanhar se o usuário está online, ou para se conectar a uma sala de bate-papo. Você pode não encontrar esses Hooks no React, mas pode criar seus próprios Hooks para as necessidades do seu aplicativo From ad4f5c7c9555f65d6b889e85427ba3fdfa4e7159 Mon Sep 17 00:00:00 2001 From: Serhii Palamarchuk Date: Tue, 30 May 2023 19:57:57 +0300 Subject: [PATCH 20/67] Update NextJs link (#6053) --- .../reference/react-dom/server/renderToPipeableStream.md | 2 +- .../reference/react-dom/server/renderToReadableStream.md | 2 +- src/content/reference/react/Suspense.md | 2 +- src/content/reference/react/useDeferredValue.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md index dee690372..6a9021e02 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -286,7 +286,7 @@ Streaming does not need to wait for React itself to load in the browser, or for **Only Suspense-enabled data sources will activate the Suspense component.** They include: -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/advanced-features/react-18) +- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) - Lazy-loading component code with [`lazy`](/reference/react/lazy) Suspense **does not** detect when data is fetched inside an Effect or event handler. diff --git a/src/content/reference/react-dom/server/renderToReadableStream.md b/src/content/reference/react-dom/server/renderToReadableStream.md index d6d5b3264..8ef42aa71 100644 --- a/src/content/reference/react-dom/server/renderToReadableStream.md +++ b/src/content/reference/react-dom/server/renderToReadableStream.md @@ -285,7 +285,7 @@ Streaming does not need to wait for React itself to load in the browser, or for **Only Suspense-enabled data sources will activate the Suspense component.** They include: -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/advanced-features/react-18) +- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) - Lazy-loading component code with [`lazy`](/reference/react/lazy) Suspense **does not** detect when data is fetched inside an Effect or event handler. diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index f24c98c7d..27add6035 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -252,7 +252,7 @@ async function getAlbums() { **Only Suspense-enabled data sources will activate the Suspense component.** They include: -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/advanced-features/react-18) +- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) - Lazy-loading component code with [`lazy`](/reference/react/lazy) Suspense **does not** detect when data is fetched inside an Effect or event handler. diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 3f2a8a5d9..f25054542 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -84,7 +84,7 @@ During updates, the deferred value will "lag behin This example assumes you use one of Suspense-enabled data sources: -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/advanced-features/react-18) +- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) - Lazy-loading component code with [`lazy`](/reference/react/lazy) [Learn more about Suspense and its limitations.](/reference/react/Suspense) From 4e62b6b8684a8ab124d66c91729a4dc58b6fc351 Mon Sep 17 00:00:00 2001 From: jhonmike Date: Wed, 31 May 2023 11:13:52 -0300 Subject: [PATCH 21/67] fix: conflict --- src/content/reference/react-dom/components/progress.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/content/reference/react-dom/components/progress.md b/src/content/reference/react-dom/components/progress.md index 1411106d3..53fc64a5d 100644 --- a/src/content/reference/react-dom/components/progress.md +++ b/src/content/reference/react-dom/components/progress.md @@ -34,13 +34,8 @@ Para exibir um indicador de progresso, renderize o componente [`` nati Adicionalmente, `` suporta estas props: -<<<<<<< HEAD * [`max`](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/progress#attr-max): Um número. Especifica o `value` máximo. Seu valor padrão é `1`. * [`value`](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/progress#attr-value): Um número entre `0` e `max`, ou `null` para progresso indeterminado. Especifica o quanto foi feito. -======= -* [`max`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#attr-max): A number. Specifies the maximum `value`. Defaults to `1`. -* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#attr-value): A number between `0` and `max`, or `null` for indeterminate progress. Specifies how much was done. ->>>>>>> 3364c93feb358a7d1ac2e8d8b0468c3e32214062 --- From 4184c0f5608ef80d6cec4e1c42dfa9c6f3c9ad92 Mon Sep 17 00:00:00 2001 From: J <124119483+escwxyz@users.noreply.github.com> Date: Wed, 31 May 2023 16:15:21 +0200 Subject: [PATCH 22/67] Fix a missing word in useLayoutEffect (#6078) --- src/content/reference/react/useLayoutEffect.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useLayoutEffect.md b/src/content/reference/react/useLayoutEffect.md index d30ebbd16..5af3ec5a6 100644 --- a/src/content/reference/react/useLayoutEffect.md +++ b/src/content/reference/react/useLayoutEffect.md @@ -26,7 +26,7 @@ useLayoutEffect(setup, dependencies?) ### `useLayoutEffect(setup, dependencies?)` {/*useinsertioneffect*/} -Call `useLayoutEffect` perform the layout measurements before the browser repaints the screen: +Call `useLayoutEffect` to perform the layout measurements before the browser repaints the screen: ```js import { useState, useRef, useLayoutEffect } from 'react'; From 288bde2765dffbf04d8fc055d1aeac900b004c5c Mon Sep 17 00:00:00 2001 From: Alexandre Costa Date: Wed, 31 May 2023 11:19:54 -0300 Subject: [PATCH 23/67] Translates `responding-to-events` page (#684) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * translates responding-to-events page * fix responding-to-events analytics translation * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> * Update src/content/learn/responding-to-events.md Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> --------- Co-authored-by: Natã Pereira <57020127+natrodrigo@users.noreply.github.com> --- src/content/learn/responding-to-events.md | 309 +++++++++++----------- 1 file changed, 154 insertions(+), 155 deletions(-) diff --git a/src/content/learn/responding-to-events.md b/src/content/learn/responding-to-events.md index 4450c4613..83b5439eb 100644 --- a/src/content/learn/responding-to-events.md +++ b/src/content/learn/responding-to-events.md @@ -1,24 +1,24 @@ --- -title: Responding to Events +title: Respondendo a Eventos --- -React lets you add *event handlers* to your JSX. Event handlers are your own functions that will be triggered in response to interactions like clicking, hovering, focusing form inputs, and so on. +O React permite você adicionar *manipuladores de eventos* (event handlers) ao seu JSX. Os manipuladores de eventos são funções independentes que são acionadas em resposta a interações como clicar com o mouse, passar o cursor do mouse sobre um certo elemento, focar em campos de formulário, entre outros. -* Different ways to write an event handler -* How to pass event handling logic from a parent component -* How events propagate and how to stop them +* Diferentes maneiras de escrever um manipulador de eventos +* Como herdar a lógica de manipulação de eventos de um componente pai +* Como os eventos se propagam e como pará-los -## Adding event handlers {/*adding-event-handlers*/} +## Adicionando manipuladores de eventos {/*adding-event-handlers*/} -To add an event handler, you will first define a function and then [pass it as a prop](/learn/passing-props-to-a-component) to the appropriate JSX tag. For example, here is a button that doesn't do anything yet: +Para adicionar um manipulador de eventos, primeiro defina uma função e depois [passe-a como uma prop](/learn/passing-props-to-a-component) para o elemento JSX desejado. Por exemplo, aqui temos um botão que ainda não faz nada: @@ -26,7 +26,7 @@ To add an event handler, you will first define a function and then [pass it as a export default function Button() { return ( ); } @@ -34,23 +34,23 @@ export default function Button() { -You can make it show a message when a user clicks by following these three steps: +Seguindo esses três passos, você poderá fazer com que uma mensagem seja exibida quando um usuário clicar no botão: -1. Declare a function called `handleClick` *inside* your `Button` component. -2. Implement the logic inside that function (use `alert` to show the message). -3. Add `onClick={handleClick}` to the ` ); } @@ -62,77 +62,76 @@ button { margin-right: 10px; } -You defined the `handleClick` function and then [passed it as a prop](/learn/passing-props-to-a-component) to ` ); } function UploadButton() { return ( - ); } @@ -207,7 +206,7 @@ function UploadButton() { export default function Toolbar() { return (
- +
); @@ -220,22 +219,22 @@ button { margin-right: 10px; } -Here, the `Toolbar` component renders a `PlayButton` and an `UploadButton`: +Aqui, o componente `Toolbar` renderiza o componente `PlayButton` e o componente`UploadButton`: -- `PlayButton` passes `handlePlayClick` as the `onClick` prop to the `Button` inside. -- `UploadButton` passes `() => alert('Uploading!')` as the `onClick` prop to the `Button` inside. +- O `PlayButton` passa o `handlePlayClick` como prop `onClick` para o `Button` dentro dele. +- O `UploadButton` passa `() => alert('Enviando!')` como a prop `onClick` para o `Button` dentro. -Finally, your `Button` component accepts a prop called `onClick`. It passes that prop directly to the built-in browser ` -

); @@ -268,9 +267,9 @@ button { margin-right: 10px; }
-In this example, `
); @@ -312,19 +311,19 @@ button { margin-right: 10px; } -Notice how the `App` component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That's an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they're used later. - +Note como o componente `App` não precisa saber *o que* o componente `Toolbar` fará com o `onPlayMovie` ou `onUploadImage`. Isso é um detalhe de implementação da `Toolbar`. Aqui, a `Toolbar` os passa como manipuladores `onClick` para seus componentes `Button`, mas posteriormente pode acioná-los também em um atalho de teclado. Nomear as props com base em interações específicas da aplicação, como `onPlayMovie`, oferece a flexibilidade para alterar como elas são usadas no futuro. + -Make sure that you use the appropriate HTML tags for your event handlers. For example, to handle clicks, use [` -
); @@ -355,19 +354,19 @@ button { margin: 5px; } -If you click on either button, its `onClick` will run first, followed by the parent `
`'s `onClick`. So two messages will appear. If you click the toolbar itself, only the parent `
`'s `onClick` will run. +Se você clicar em qualquer um dos botões, o `onClick` do botão clicado será executado primeiro e, em seguida, o `onClick` da `
` pai será executado. Como resultado, duas mensagens serão exibidas. Se você clicar na toolbar, apenas o `onClick` da `
` pai será executado. -All events propagate in React except `onScroll`, which only works on the JSX tag you attach it to. +Todos os eventos se propagam no React, exceto `onScroll`, que funciona apenas na tag JSX à qual foi adicionado. -### Stopping propagation {/*stopping-propagation*/} +### Interrompendo a propagação {/*stopping-propagation*/} -Event handlers receive an **event object** as their only argument. By convention, it's usually called `e`, which stands for "event". You can use this object to read information about the event. +Os manipuladores de eventos recebem um **event object** como único argumento. Por convenção, ele é normalmente chamado de `e`, que significa "event", em inglês. Você pode usar esse objeto para obter informações sobre o evento. -That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` component does: +Esse event object também permite que você interrompa a propagação. Caso deseje que um evento não chegue aos componentes pai, você precisa chamar `e.stopPropagation()` como no exemplo do componente `Button` abaixo: @@ -386,13 +385,13 @@ function Button({ onClick, children }) { export default function Toolbar() { return (
{ - alert('You clicked on the toolbar!'); + alert('Você clicou na toolbar!'); }}> - -
); @@ -409,43 +408,43 @@ button { margin: 5px; }
-When you click on a button: +Ao clicar em um dos botões: -1. React calls the `onClick` handler passed to `
``` -Each event propagates in three phases: +Cada evento se propaga em três fases -1. It travels down, calling all `onClickCapture` handlers. -2. It runs the clicked element's `onClick` handler. -3. It travels upwards, calling all `onClick` handlers. +1. Ele se propaga para baixo, chamando todos os manipuladores `onClickCapture`. +2. Ele executa o manipulador `onClick` do elemento clicado. +3. Ele se propaga para cima, chamando todos os manipuladores `onClick`. -Capture events are useful for code like routers or analytics, but you probably won't use them in app code. +Os eventos de captura são úteis para códigos como roteadores ou análises, mas você provavelmente não os usará no código de uma aplicação. -### Passing handlers as alternative to propagation {/*passing-handlers-as-alternative-to-propagation*/} +### Passando manipuladores como alternativa à propagação {/*passing-handlers-as-alternative-to-propagation*/} -Notice how this click handler runs a line of code _and then_ calls the `onClick` prop passed by the parent: +Observe como esse manipulador de cliques executa uma linha de código _e depois_ chama a prop `onClick` passada pelo pai: ```js {4,5} function Button({ onClick, children }) { @@ -460,22 +459,22 @@ function Button({ onClick, children }) { } ``` -You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child component handle the event, while also letting the parent component specify some additional behavior. Unlike propagation, it's not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event. +Você também pode adicionar mais código a esse manipulador antes de chamar o manipulador de eventos `onClick` do elemento pai. Esse padrão fornece uma *alternativa* à propagação. Ele permite que o componente filho manipule o evento, mas ainda permitindo que o componente pai especifique algum comportamento adicional. Diferente da propagação, esse padrão não é automático, mas a sua vantagem é que você pode seguir claramente toda a cadeia de código executada como resultado de algum evento. -If you rely on propagation and it's difficult to trace which handlers execute and why, try this approach instead. +Caso você esteja dependendo da propagação de eventos e tenha dificuldade em rastrear quais manipuladores estão sendo executados e por quê, tente essa abordagem. -### Preventing default behavior {/*preventing-default-behavior*/} +### Removendo comportamento padrão {/*preventing-default-behavior*/} -Some browser events have default behavior associated with them. For example, a `` submit event, which happens when a button inside of it is clicked, will reload the whole page by default: +Alguns eventos do navegador têm um comportamento padrão associado a eles. Por exemplo, um evento de envio de formulário ``, que acontece quando um botão dentro dele é clicado, recarregará a página inteira por padrão: ```js export default function Signup() { return ( - alert('Submitting!')}> + alert('Enviando!')}> - + ); } @@ -487,7 +486,7 @@ button { margin-left: 5px; } -You can call `e.preventDefault()` on the event object to stop this from happening: +É possível chamar `e.preventDefault()` no objeto do evento para impedir que isso aconteça: @@ -496,10 +495,10 @@ export default function Signup() { return (
{ e.preventDefault(); - alert('Submitting!'); + alert('Enviando!'); }}> - +
); } @@ -511,28 +510,28 @@ button { margin-left: 5px; }
-Don't confuse `e.stopPropagation()` and `e.preventDefault()`. They are both useful, but are unrelated: +Não confunda `e.stopPropagation()` com `e.preventDefault()`. Ambos são úteis, mas não estão relacionados: -* [`e.stopPropagation()`](https://developer.mozilla.org/docs/Web/API/Event/stopPropagation) stops the event handlers attached to the tags above from firing. -* [`e.preventDefault()` ](https://developer.mozilla.org/docs/Web/API/Event/preventDefault) prevents the default browser behavior for the few events that have it. +* [`e.stopPropagation()`](https://developer.mozilla.org/pt-BR/docs/Web/API/Event/stopPropagation) impede que os manipuladores de eventos associados às tags superiores sejam acionados. +* [`e.preventDefault()` ](https://developer.mozilla.org/pt-BR/docs/Web/API/Event/preventDefault) impede que o navegador execute o comportamento padrão associado a determinados eventos. -## Can event handlers have side effects? {/*can-event-handlers-have-side-effects*/} +## Os manipuladores de eventos podem ter efeitos colaterais? {/*can-event-handlers-have-side-effects*/} -Absolutely! Event handlers are the best place for side effects. +Sem dúvida! Os manipuladores de eventos são o local ideal para efeitos colaterais. -Unlike rendering functions, event handlers don't need to be [pure](/learn/keeping-components-pure), so it's a great place to *change* something—for example, change an input's value in response to typing, or change a list in response to a button press. However, in order to change some information, you first need some way to store it. In React, this is done by using [state, a component's memory.](/learn/state-a-components-memory) You will learn all about it on the next page. +Ao contrário das funções de renderização, os manipuladores de eventos não precisam ser [puros](/learn/keeping-components-pure), o que significa que é o local ideal para realizar *modificações*, por exemplo, alterar o valor de um input em resposta à digitação, ou alterar uma lista em resposta ao clique de um botão. No entanto, para alterar alguma informação, você primeiro precisa de uma maneira de armazenar essa informação. No React, isso é feito usando o [state, a memória de um componente.](/learn/state-a-components-memory) Você aprenderá tudo sobre isso na próxima página. -* You can handle events by passing a function as a prop to an element like ` ); } @@ -569,7 +568,7 @@ export default function LightSwitch() { -The problem is that ` ); } @@ -594,7 +593,7 @@ export default function LightSwitch() { -Alternatively, you could wrap the call into another function, like ` ); } @@ -621,11 +620,11 @@ export default function LightSwitch() { -#### Wire up the events {/*wire-up-the-events*/} +#### Conecte os eventos {/*wire-up-the-events*/} -This `ColorSwitch` component renders a button. It's supposed to change the page color. Wire it up to the `onChangeColor` event handler prop it receives from the parent so that clicking the button changes the color. +Este componente `ColorSwitch` renderiza um botão que deveria alterar a cor da página. Conecte-o ao manipulador de eventos `onChangeColor` que ele recebe do pai. Assim, ao clicar no botão, a cor da página será alterada. -After you do this, notice that clicking the button also increments the page click counter. Your colleague who wrote the parent component insists that `onChangeColor` does not increment any counters. What else might be happening? Fix it so that clicking the button *only* changes the color, and does _not_ increment the counter. +Depois de fazer isso, perceba que ao clicar no botão, o contador de cliques da página também é incrementado. Seu colega, que escreveu o componente pai, insiste que o `onChangeColor` não deveria incrementar o contador. O que mais poderia estar acontecendo? Corrija o problema para que ao clicar no botão, *apenas* altere a cor e _não_ incremente o contador. @@ -635,7 +634,7 @@ export default function ColorSwitch({ }) { return ( ); } @@ -669,7 +668,7 @@ export default function App() {

-

Clicks on the page: {clicks}

+

Cliques na página: {clicks}

); } @@ -679,9 +678,9 @@ export default function App() { -First, you need to add the event handler, like ` -#### Find and fix the mutation {/*find-and-fix-the-mutation*/} +#### Encontre e corrija a mutação {/*find-and-fix-the-mutation*/} -There is a draggable box on a static background. You can change the box's color using the select input. +Há uma caixa arrastável em um fundo estático. Você pode alterar a cor da caixa usando a lista de seleção. -But there is a bug. If you move the box first, and then change its color, the background (which isn't supposed to move!) will "jump" to the box position. But this should not happen: the `Background`'s `position` prop is set to `initialPosition`, which is `{ x: 0, y: 0 }`. Why is the background moving after the color change? +Mas há um erro. Se você mover a caixa primeiro e depois mudar sua cor, o fundo (que não deveria se mover!) "pulará" para a posição da caixa. Mas isso não deveria acontecer: a propriedade `position` do `Background` é definida como `initialPosition`, que é `{ x: 0, y: 0 }`. Por que o fundo está se movendo após a mudança de cor? -Find the bug and fix it. +Encontre o erro e corrija-o. -If something unexpected changes, there is a mutation. Find the mutation in `App.js` and fix it. +Se algo inesperado muda, é porque há uma mutação. Encontre a mutação em `App.js` e corrija-a. @@ -1020,9 +1018,9 @@ export default function Canvas() { value={shape.color} onChange={handleColorChange} > - - - + + + - Drag me! + Arraste-me! ); @@ -1130,9 +1128,9 @@ select { margin-bottom: 10px; } -The problem was in the mutation inside `handleMove`. It mutated `shape.position`, but that's the same object that `initialPosition` points at. This is why both the shape and the background move. (It's a mutation, so the change doesn't reflect on the screen until an unrelated update--the color change--triggers a re-render.) +O problema estava na mutação dentro de `handleMove`. Ele alterou `shape.position`, mas esse é o mesmo objeto para o qual `initialPosition` aponta. É por isso que tanto a forma quanto o plano de fundo se movem. (É uma mutação, portanto, a alteração não é refletida na tela até que uma atualização não relacionada -- a alteração de cor -- acione uma nova renderização). -The fix is to remove the mutation from `handleMove`, and use the spread syntax to copy the shape. Note that `+=` is a mutation, so you need to rewrite it to use a regular `+` operation. +A solução é remover a mutação de `handleMove` e usar a sintaxe de espalhamento para copiar a forma. Observe que `+=` é uma mutação, portanto, você precisa reescrevê-la para usar uma operação `+` regular. @@ -1175,9 +1173,9 @@ export default function Canvas() { value={shape.color} onChange={handleColorChange} > - - - + + + - Drag me! + Arraste-me! ); @@ -1285,9 +1283,9 @@ select { margin-bottom: 10px; } -#### Update an object with Immer {/*update-an-object-with-immer*/} +#### Atualize um objeto com Immer {/*update-an-object-with-immer*/} -This is the same buggy example as in the previous challenge. This time, fix the mutation by using Immer. For your convenience, `useImmer` is already imported, so you need to change the `shape` state variable to use it. +Este é o mesmo exemplo com erros do desafio anterior. Desta vez, corrija a mutação usando Immer. Para sua conveniência, o `useImmer` já está importado, portanto, você precisa alterar a variável `shape` do state para usá-lo. @@ -1326,9 +1324,9 @@ export default function Canvas() { value={shape.color} onChange={handleColorChange} > - - - + + + - Drag me! + Arraste-me! ); @@ -1454,7 +1452,7 @@ select { margin-bottom: 10px; } -This is the solution rewritten with Immer. Notice how the event handlers are written in a mutating fashion, but the bug does not occur. This is because under the hood, Immer never mutates the existing objects. +Esta é a solução reescrita com Immer. Observe como os manipuladores de eventos são escritos de forma mutante, mas o erro não ocorre. Isso se deve ao fato de que, por baixo dos panos, a Immer nunca muta os objetos existentes. @@ -1493,9 +1491,9 @@ export default function Canvas() { value={shape.color} onChange={handleColorChange} > - - - + + + - Drag me! + Arraste-me! ); From 6dec14aa67b75fce67c5035e1c7e151504f87f3d Mon Sep 17 00:00:00 2001 From: Nivaldo Farias Date: Wed, 31 May 2023 11:22:15 -0300 Subject: [PATCH 25/67] =?UTF-8?q?Tradu=C3=A7=C3=A3o=20da=20p=C3=A1gina=20`?= =?UTF-8?q?state-as-a-snapshot.md`=20=20(#690)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * translate `learn/state-as-a-snapshot.md` to pt-BR * translate all `state` to native `estado`, excluding title * update branch; add text --- src/content/learn/state-as-a-snapshot.md | 172 +++++++++++------------ 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/src/content/learn/state-as-a-snapshot.md b/src/content/learn/state-as-a-snapshot.md index 503b0abb4..99bebd8f0 100644 --- a/src/content/learn/state-as-a-snapshot.md +++ b/src/content/learn/state-as-a-snapshot.md @@ -1,27 +1,27 @@ --- -title: State as a Snapshot +title: State como uma Foto Instantânea --- -State variables might look like regular JavaScript variables that you can read and write to. However, state behaves more like a snapshot. Setting it does not change the state variable you already have, but instead triggers a re-render. +Variáveis de estado podem parecer variáveis JavaScript regulares das quais você pode ler e escrever. No entanto, estado se comporta mais como uma foto instantânea. Modificá-lo não altera a variável de estado que você já tem, mas sim dispara uma nova renderização. -* How setting state triggers re-renders -* When and how state updates -* Why state does not update immediately after you set it -* How event handlers access a "snapshot" of the state +* Como manipulações de estado disparam novas renderizações +* Quando e como atualizar o estado +* Por que o estado não é atualizado imediatamente após você modificá-lo +* Como os manipuladores de eventos acessam uma "foto instantânea" do estado -## Setting state triggers renders {/*setting-state-triggers-renders*/} +## Manipulações de estado disparam novas renderizações {/*setting-state-triggers-renders*/} -You might think of your user interface as changing directly in response to the user event like a click. In React, it works a little differently from this mental model. On the previous page, you saw that [setting state requests a re-render](/learn/render-and-commit#step-1-trigger-a-render) from React. This means that for an interface to react to the event, you need to *update the state*. +Você pode pensar que sua interface do usuário muda diretamente em resposta ao evento do usuário, como um clique. No React, isso funciona de forma um pouco diferente deste modelo mental. Na página anterior, você viu que [manipular o estado solicita uma nova renderização](/learn/render-and-commit#step-1-trigger-a-render) do React. Isso significa que, para uma interface reagir ao evento, você precisa *atualizar o state*. -In this example, when you press "send", `setIsSent(true)` tells React to re-render the UI: +Neste exemplo, quando você pressiona "enviar", `setIsSent(true)` diz ao React para renderizar novamente a interface: @@ -30,9 +30,9 @@ import { useState } from 'react'; export default function Form() { const [isSent, setIsSent] = useState(false); - const [message, setMessage] = useState('Hi!'); + const [message, setMessage] = useState('Olá!'); if (isSent) { - return

Your message is on its way!

+ return

Sua mensagem está a caminho!

} return (
{ @@ -45,7 +45,7 @@ export default function Form() { value={message} onChange={e => setMessage(e.target.value)} /> - +
); } @@ -61,43 +61,43 @@ label, textarea { margin-bottom: 10px; display: block; }
-Here's what happens when you click the button: +Veja o que acontece quando você clica no botão: -1. The `onSubmit` event handler executes. -2. `setIsSent(true)` sets `isSent` to `true` and queues a new render. -3. React re-renders the component according to the new `isSent` value. +1. O manipulador de evento `onSubmit` é executado. +2. `setIsSent(true)` define `isSent` como `true` e enfileira uma nova renderização. +3. O React rerrenderiza o componente de acordo com o novo valor de `isSent`. -Let's take a closer look at the relationship between state and rendering. +Vamos dar uma olhada mais de perto na relação entre estado e renderização. -## Rendering takes a snapshot in time {/*rendering-takes-a-snapshot-in-time*/} +## Renderização tira uma foto instantânea {/*rendering-takes-a-snapshot-in-time*/} -["Rendering"](/learn/render-and-commit#step-2-react-renders-your-components) means that React is calling your component, which is a function. The JSX you return from that function is like a snapshot of the UI in time. Its props, event handlers, and local variables were all calculated **using its state at the time of the render.** +["Renderizar"](/learn/render-and-commit#step-2-react-renders-your-components) significa que o React está chamando seu componente, que é uma função. O JSX que você retorna dessa função é como uma foto instantânea da interface do usuário em um determinado momento. Suas *props*, manipuladores de eventos e variáveis locais foram todas calculadas **usando seu estado no momento da renderização.** -Unlike a photograph or a movie frame, the UI "snapshot" you return is interactive. It includes logic like event handlers that specify what happens in response to inputs. React updates the screen to match this snapshot and connects the event handlers. As a result, pressing a button will trigger the click handler from your JSX. +Ao contrário de uma fotografia ou um *frame* de um filme, a foto instantânea da interface do usuário que você retorna é interativa. Ela inclui lógica como manipuladores de eventos que especificam o que acontece em resposta às entradas. O React atualiza a tela para corresponder a essa foto instantânea e conecta os manipuladores de eventos. Como resultado, pressionar um botão acionará o manipulador de clique do seu JSX. -When React re-renders a component: +Quando o React rerrenderiza um componente: -1. React calls your function again. -2. Your function returns a new JSX snapshot. -3. React then updates the screen to match the snapshot you've returned. +1. O React chama sua função novamente. +2. Sua função retorna uma nova foto instantânea do JSX. +3. O React, então, atualiza a tela para corresponder à foto instantânea que você retornou. - - - + + + -As a component's memory, state is not like a regular variable that disappears after your function returns. State actually "lives" in React itself--as if on a shelf!--outside of your function. When React calls your component, it gives you a snapshot of the state for that particular render. Your component returns a snapshot of the UI with a fresh set of props and event handlers in its JSX, all calculated **using the state values from that render!** +Assim como a memória de um componente, o estado não é como uma variável regular que desaparece após a função retornar. O estado realmente "vive" no React, fora da sua função. Quando o React chama seu componente, ele lhe dá uma foto instantânea do estado para aquela renderização específica. Seu componente retorna uma foto instantânea da interface do usuário com um novo conjunto de *props* e manipuladores de eventos em seu JSX, todos calculados **usando os valores do estado daquela renderização!** - - - + + + -Here's a little experiment to show you how this works. In this example, you might expect that clicking the "+3" button would increment the counter three times because it calls `setNumber(number + 1)` three times. +Aqui está um pequeno experimento para mostrar como isso funciona. Neste exemplo, você pode esperar que clicar no botão "+3" incremente o contador três vezes porque ele chama `setNumber(number + 1)` três vezes. -See what happens when you click the "+3" button: +Veja o que acontece quando você clica no botão "+3": @@ -127,9 +127,9 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } -Notice that `number` only increments once per click! +Observe que `number` só incrementa uma vez por clique! -**Setting state only changes it for the *next* render.** During the first render, `number` was `0`. This is why, in *that render's* `onClick` handler, the value of `number` is still `0` even after `setNumber(number + 1)` was called: +**Manipular o estado o altera apenas para a *próxima* renderização.** Durante a primeira renderização, `number` era `0`. É por isso que, no manipulador de `onClick` *daquela renderização*, o valor de `number` ainda é `0` mesmo depois de `setNumber(number + 1)` ter sido chamado: ```js ``` -Here is what this button's click handler tells React to do: +Aqui está o que o manipulador de `onClick` deste botão diz ao React para fazer: 1. `setNumber(number + 1)`: `number` is `0` so `setNumber(0 + 1)`. - - React prepares to change `number` to `1` on the next render. + - O React se prepara para mudar `number` para `1` na próxima renderização. 2. `setNumber(number + 1)`: `number` is `0` so `setNumber(0 + 1)`. - - React prepares to change `number` to `1` on the next render. + - O React se prepara para mudar `number` para `1` na próxima renderização. 3. `setNumber(number + 1)`: `number` is `0` so `setNumber(0 + 1)`. - - React prepares to change `number` to `1` on the next render. + - O React se prepara para mudar `number` para `1` na próxima renderização. -Even though you called `setNumber(number + 1)` three times, in *this render's* event handler `number` is always `0`, so you set the state to `1` three times. This is why, after your event handler finishes, React re-renders the component with `number` equal to `1` rather than `3`. +Mesmo que você tenha chamado `setNumber(number + 1)` três vezes, no manipulador de eventos *daquela renderização* `number` é sempre `0`, então você definiu o estado para `1` três vezes. É por isso que, depois que o manipulador de eventos termina, o React rerrenderiza o componente com `number` igual a `1` em vez de `3`. -You can also visualize this by mentally substituting state variables with their values in your code. Since the `number` state variable is `0` for *this render*, its event handler looks like this: +Você também pode visualizar isso substituindo mentalmente as variáveis de estado por seus valores no seu código. Como a variável de estado `number` é `0` para *essa renderização*, seu manipulador de eventos se parece com isto: ```js ``` -For the next render, `number` is `1`, so *that render's* click handler looks like this: +Para a próxima renderização, `number` é `1`, então o manipulador de eventos *daquela renderização* se parece com isto: ```js ``` -This is why clicking the button again will set the counter to `2`, then to `3` on the next click, and so on. +É por isso que clicar no botão novamente definirá o contador para `2`, depois para `3` no próximo clique e assim por diante. -## State over time {/*state-over-time*/} +## Estado ao longo do tempo {/*state-over-time*/} -Well, that was fun. Try to guess what clicking this button will alert: +Bem, isso foi divertido. Tente adivinhar o que clicar neste botão irá alertar: @@ -203,14 +203,14 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } -If you use the substitution method from before, you can guess that the alert shows "0": +Se você usar o método de substituição de antes, você pode adivinhar que o alerta mostra "0": ```js setNumber(0 + 5); alert(0); ``` -But what if you put a timer on the alert, so it only fires _after_ the component re-rendered? Would it say "0" or "5"? Have a guess! +Mas e se você colocar um temporizador no alerta, para que ele só seja disparado *depois* do componente ser renderizado novamente? Ele diria "0" ou "5"? Dê um palpite! @@ -241,7 +241,7 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } -Surprised? If you use the substitution method, you can see the "snapshot" of the state passed to the alert. +Surpreso? Se você usar o método de substituição, você pode ver a "instantânea" do estado passado para o alerta. ```js setNumber(0 + 5); @@ -250,16 +250,16 @@ setTimeout(() => { }, 3000); ``` -The state stored in React may have changed by the time the alert runs, but it was scheduled using a snapshot of the state at the time the user interacted with it! +O estado armazenado no React pode ter mudado no momento em que o alerta é executado, mas ele foi agendado usando uma "instantânea" do estado no momento em que o usuário interagiu com ele! -**A state variable's value never changes within a render,** even if its event handler's code is asynchronous. Inside *that render's* `onClick`, the value of `number` continues to be `0` even after `setNumber(number + 5)` was called. Its value was "fixed" when React "took the snapshot" of the UI by calling your component. +**O valor de uma variável de estado nunca muda dentro de uma renderização,** mesmo que o código do manipulador de eventos seja assíncrono. Dentro do `onClick` *daquela renderização*, o valor de `number` continua sendo `0` mesmo depois que `setNumber(number + 5)` foi chamado. Seu valor foi "fixado" quando o React "tirou a foto" da UI chamando seu componente. -Here is an example of how that makes your event handlers less prone to timing mistakes. Below is a form that sends a message with a five-second delay. Imagine this scenario: +Aqui está um exemplo de como isso torna seus manipuladores de eventos menos propensos a erros de sincronização. Abaixo está um formulário que envia uma mensagem com um atraso de cinco segundos. Imagine este cenário: -1. You press the "Send" button, sending "Hello" to Alice. -2. Before the five-second delay ends, you change the value of the "To" field to "Bob". +1. Você pressiona o botão "Enviar", enviando "Olá" para Alice. +2. Antes que o atraso de cinco segundos termine, você muda o valor do campo "Para" para "Bob". -What do you expect the `alert` to display? Would it display, "You said Hello to Alice"? Or would it display, "You said Hello to Bob"? Make a guess based on what you know, and then try it: +O que você espera que o `alert` mostre? Ele exibiria "Você disse Olá para Alice"? Ou exibiria "Você disse Olá para Bob"? Faça uma suposição com base no que você sabe e, em seguida, tente: @@ -268,19 +268,19 @@ import { useState } from 'react'; export default function Form() { const [to, setTo] = useState('Alice'); - const [message, setMessage] = useState('Hello'); + const [message, setMessage] = useState('Olá'); function handleSubmit(e) { e.preventDefault(); setTimeout(() => { - alert(`You said ${message} to ${to}`); + alert(`Você disse ${message} para ${to}`); }, 5000); } return (

- The password should contain at least 18 characters + A senha deve conter pelo menos 18 caracteres

``` -However, hardcoding IDs like this is not a good practice in React. A component may be rendered more than once on the page--but IDs have to be unique! Instead of hardcoding an ID, generate a unique ID with `useId`: +No entanto, codificar IDs como esse não é uma boa prática no React. Um componente pode ser renderizado mais de uma vez na página, mas os IDs devem ser únicos! Em vez de codificar um ID, gere um ID único com `useId`: ```js {4,11,14} import { useId } from 'react'; @@ -106,21 +106,21 @@ function PasswordField() { return ( <>

- The password should contain at least 18 characters + A senha deve conter pelo menos 18 caracteres

); } ``` -Now, even if `PasswordField` appears multiple times on the screen, the generated IDs won't clash. +Agora, mesmo que `PasswordField` apareça várias vezes na tela, os IDs gerados não entrarão em conflito. @@ -132,14 +132,14 @@ function PasswordField() { return ( <>

- The password should contain at least 18 characters + A senha deve conter pelo menos 18 caracteres

); @@ -148,9 +148,9 @@ function PasswordField() { export default function App() { return ( <> -

Choose password

+

Escolha uma senha

-

Confirm password

+

Confirme a senha

); @@ -163,33 +163,33 @@ input { margin: 5px; }
-[Watch this video](https://www.youtube.com/watch?v=0dNzNcuEuOo) to see the difference in the user experience with assistive technologies. +[Assista à esse vídeo](https://www.youtube.com/watch?v=0dNzNcuEuOo) para ver a diferença na experiência do usuário com tecnologias assistivas. -With [server rendering](/reference/react-dom/server), **`useId` requires an identical component tree on the server and the client**. If the trees you render on the server and the client don't match exactly, the generated IDs won't match. +Com a [renderização do servidor](/reference/react-dom/server), **`useId` requer uma árvore de componentes idêntica no servidor e no cliente**. Se as árvores que você renderizar no servidor e no cliente não corresponderem exatamente, os IDs gerados não corresponderão. -#### Why is useId better than an incrementing counter? {/*why-is-useid-better-than-an-incrementing-counter*/} +#### Por que useId é melhor que um contador de incremento? {/*why-is-useid-better-than-an-incrementing-counter*/} -You might be wondering why `useId` is better than incrementing a global variable like `nextId++`. +Você pode estar se perguntando por que `useId` é melhor do que incrementar uma variável global como `nextId++`. -The primary benefit of `useId` is that React ensures that it works with [server rendering.](/reference/react-dom/server) During server rendering, your components generate HTML output. Later, on the client, [hydration](/reference/react-dom/client/hydrateRoot) attaches your event handlers to the generated HTML. For hydration to work, the client output must match the server HTML. +O principal benefício do `useId` é que o React garante que funcione com a [renderização do servidor.](/reference/react-dom/server) Durante a renderização do servidor, seus componentes geram saídas HTML. Posteriormente, no cliente, a [hidratação](/reference/react-dom/client/hydrateRoot) anexa seus manipuladores de eventos ao HTML gerado. Para que a hidratação funcione, a saída do cliente deve corresponder ao HTML do servidor. -This is very difficult to guarantee with an incrementing counter because the order in which the client components are hydrated may not match the order in which the server HTML was emitted. By calling `useId`, you ensure that hydration will work, and the output will match between the server and the client. +Isso é muito difícil de garantir com um contador de incremento porque a ordem na qual os componentes do cliente são hidratados pode não corresponder à ordem na qual o HTML do servidor foi emitido. Ao chamar `useId`, você garante que a hidratação funcionará e a saída corresponderá entre o servidor e o cliente. -Inside React, `useId` is generated from the "parent path" of the calling component. This is why, if the client and the server tree are the same, the "parent path" will match up regardless of rendering order. +Dentro do React, `useId` é gerado a partir do "caminho pai" do componente chamado. É por isso que, se o cliente e a árvore do servidor forem iguais, o "caminho pai" corresponderá, independentemente da ordem de renderização. --- -### Generating IDs for several related elements {/*generating-ids-for-several-related-elements*/} +### Gerando IDs para vários elementos relacionados {/*generating-ids-for-several-related-elements*/} -If you need to give IDs to multiple related elements, you can call `useId` to generate a shared prefix for them: +Se você precisar fornecer IDs para vários elementos relacionados, você pode chamar `useId` para gerar um prefixo compartilhado para eles: @@ -200,10 +200,10 @@ export default function Form() { const id = useId(); return ( - +
- + ); @@ -216,20 +216,20 @@ input { margin: 5px; }
-This lets you avoid calling `useId` for every single element that needs a unique ID. +Isso permite que você evite chamar `useId` para cada elemento que precisa de um ID único. --- -### Specifying a shared prefix for all generated IDs {/*specifying-a-shared-prefix-for-all-generated-ids*/} +### Especificando um prefixo compartilhado para todos os IDs gerados {/*specifying-a-shared-prefix-for-all-generated-ids*/} -If you render multiple independent React applications on a single page, pass `identifierPrefix` as an option to your [`createRoot`](/reference/react-dom/client/createRoot#parameters) or [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) calls. This ensures that the IDs generated by the two different apps never clash because every identifier generated with `useId` will start with the distinct prefix you've specified. +Se você renderizar várias aplicações React independentes em uma única página, passe `identifierPrefix` como uma opção para suas chamadas [`createRoot`](/reference/react-dom/client/createRoot#parameters) ou [`hydrateRoot`](/reference/react-dom/client/hydrateRoot). Isso garante que os IDs gerados pelos dois aplicativos diferentes nunca entrem em conflito porque cada identificador gerado com `useId` começará com o prefixo distinto que você especificou. ```html index.html - My app + Meu app
@@ -242,18 +242,18 @@ import { useId } from 'react'; function PasswordField() { const passwordHintId = useId(); - console.log('Generated identifier:', passwordHintId) + console.log('Identificador gerado:', passwordHintId) return ( <>

- The password should contain at least 18 characters + A senha deve conter pelo menos 18 caracteres

); @@ -262,7 +262,7 @@ function PasswordField() { export default function App() { return ( <> -

Choose password

+

Escolha uma senha

); From ca93140eb98a7ff4364a719075fccea980c55b55 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Fri, 2 Jun 2023 14:42:16 +0300 Subject: [PATCH 28/67] Fix option's mdn link (#6080) --- src/content/reference/react-dom/components/option.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/components/option.md b/src/content/reference/react-dom/components/option.md index 8d930523f..84725854c 100644 --- a/src/content/reference/react-dom/components/option.md +++ b/src/content/reference/react-dom/components/option.md @@ -23,7 +23,7 @@ The [built-in browser `