From c3ee515d4e985825206d67743ce654d517169d62 Mon Sep 17 00:00:00 2001 From: Nivaldo Farias Date: Thu, 20 Mar 2025 11:49:04 -0300 Subject: [PATCH] Translate `preserving-and-resetting-state.md` to Portuguese --- .../learn/preserving-and-resetting-state.md | 1043 ++--------------- 1 file changed, 87 insertions(+), 956 deletions(-) diff --git a/src/content/learn/preserving-and-resetting-state.md b/src/content/learn/preserving-and-resetting-state.md index d35071845..371e6b919 100644 --- a/src/content/learn/preserving-and-resetting-state.md +++ b/src/content/learn/preserving-and-resetting-state.md @@ -1,641 +1,11 @@ ---- -title: Preserving and Resetting State ---- - - - -State is isolated between components. React keeps track of which state belongs to which component based on their place in the UI tree. You can control when to preserve state and when to reset it between re-renders. - - - - - -* When React chooses to preserve or reset the state -* How to force React to reset component's state -* How keys and types affect whether the state is preserved - - - -## State is tied to a position in the render tree {/*state-is-tied-to-a-position-in-the-tree*/} - -React builds [render trees](learn/understanding-your-ui-as-a-tree#the-render-tree) for the component structure in your UI. - -When you give a component state, you might think the state "lives" inside the component. But the state is actually held inside React. React associates each piece of state it's holding with the correct component by where that component sits in the render tree. - -Here, there is only one `` JSX tag, but it's rendered at two different positions: - - - -```js -import { useState } from 'react'; - -export default function App() { - const counter = ; - return ( -
- {counter} - {counter} -
- ); -} - -function Counter() { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -label { - display: block; - clear: both; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.hover { - background: #ffffd8; -} -``` - -
- -Here's how these look as a tree: - - - - - -React tree - - - - - -**These are two separate counters because each is rendered at its own position in the tree.** You don't usually have to think about these positions to use React, but it can be useful to understand how it works. - -In React, each component on the screen has fully isolated state. For example, if you render two `Counter` components side by side, each of them will get its own, independent, `score` and `hover` states. - -Try clicking both counters and notice they don't affect each other: - - - -```js -import { useState } from 'react'; - -export default function App() { - return ( -
- - -
- ); -} - -function Counter() { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.hover { - background: #ffffd8; -} -``` - -
- -As you can see, when one counter is updated, only the state for that component is updated: - - - - - - -Updating state - - - - - - -React will keep the state around for as long as you render the same component at the same position in the tree. To see this, increment both counters, then remove the second component by unchecking "Render the second counter" checkbox, and then add it back by ticking it again: - - - -```js -import { useState } from 'react'; - -export default function App() { - const [showB, setShowB] = useState(true); - return ( -
- - {showB && } - -
- ); -} - -function Counter() { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -label { - display: block; - clear: both; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.hover { - background: #ffffd8; -} -``` - -
- -Notice how the moment you stop rendering the second counter, its state disappears completely. That's because when React removes a component, it destroys its state. - - - - - -Deleting a component - - - - - -When you tick "Render the second counter", a second `Counter` and its state are initialized from scratch (`score = 0`) and added to the DOM. - - - - - -Adding a component - - - - - -**React preserves a component's state for as long as it's being rendered at its position in the UI tree.** If it gets removed, or a different component gets rendered at the same position, React discards its state. - -## Same component at the same position preserves state {/*same-component-at-the-same-position-preserves-state*/} - -In this example, there are two different `` tags: - - - -```js -import { useState } from 'react'; - -export default function App() { - const [isFancy, setIsFancy] = useState(false); - return ( -
- {isFancy ? ( - - ) : ( - - )} - -
- ); -} - -function Counter({ isFancy }) { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - if (isFancy) { - className += ' fancy'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -label { - display: block; - clear: both; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.fancy { - border: 5px solid gold; - color: #ff6767; -} - -.hover { - background: #ffffd8; -} -``` - -
- -When you tick or clear the checkbox, the counter state does not get reset. Whether `isFancy` is `true` or `false`, you always have a `` as the first child of the `div` returned from the root `App` component: - - - - - -Updating the `App` state does not reset the `Counter` because `Counter` stays in the same position - - - - - - -It's the same component at the same position, so from React's perspective, it's the same counter. - - - -Remember that **it's the position in the UI tree--not in the JSX markup--that matters to React!** This component has two `return` clauses with different `` JSX tags inside and outside the `if`: - - - -```js -import { useState } from 'react'; - -export default function App() { - const [isFancy, setIsFancy] = useState(false); - if (isFancy) { - return ( -
- - -
- ); - } - return ( -
- - -
- ); -} - -function Counter({ isFancy }) { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - if (isFancy) { - className += ' fancy'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -label { - display: block; - clear: both; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.fancy { - border: 5px solid gold; - color: #ff6767; -} - -.hover { - background: #ffffd8; -} -``` - -
- -You might expect the state to reset when you tick checkbox, but it doesn't! This is because **both of these `` tags are rendered at the same position.** React doesn't know where you place the conditions in your function. All it "sees" is the tree you return. - -In both cases, the `App` component returns a `
` with `` as a first child. To React, these two counters have the same "address": the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic. - - - -## Different components at the same position reset state {/*different-components-at-the-same-position-reset-state*/} - -In this example, ticking the checkbox will replace `` with a `

`: - - - -```js -import { useState } from 'react'; - -export default function App() { - const [isPaused, setIsPaused] = useState(false); - return ( -

- {isPaused ? ( -

See you later!

- ) : ( - - )} - -
- ); -} - -function Counter() { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{score}

- -
- ); -} -``` - -```css -label { - display: block; - clear: both; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; - float: left; -} - -.hover { - background: #ffffd8; -} ``` - - - -Here, you switch between _different_ component types at the same position. Initially, the first child of the `
` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state. - - - - - -When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added - - - - - - - - - -When switching back, the `p` is deleted and the `Counter` is added - - - - - -Also, **when you render a different component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox: - - - -```js -import { useState } from 'react'; - -export default function App() { - const [isFancy, setIsFancy] = useState(false); - return ( -
- {isFancy ? ( -
- -
- ) : ( -
- -
- )} - -
- ); -} - -function Counter({ isFancy }) { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - if (isFancy) { - className += ' fancy'; - } - return (
setHover(true)} onPointerLeave={() => setHover(false)} > -

{score}

+

{person}'s score: {score}

@@ -645,9 +15,8 @@ function Counter({ isFancy }) { ``` ```css -label { - display: block; - clear: both; +h1 { + font-size: 18px; } .counter { @@ -657,12 +26,6 @@ label { border-radius: 4px; padding: 20px; margin: 0 20px 20px 0; - float: left; -} - -.fancy { - border: 5px solid gold; - color: #ff6767; } .hover { @@ -672,297 +35,63 @@ label { -The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `div` to a `section`. When the child `div` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well. - - - - - -When `section` changes to `div`, the `section` is deleted and the new `div` is added - - - - - - +Here's how the `key` affects the behavior: - +* React sees `` and `` as *different* components, even if they are rendered in the same place. +* When you change `isPlayerA`, React will *destroy* the old `Counter`, and mount a new `Counter` from scratch. +* Each `Counter` will have its own, independent state. -When switching back, the `div` is deleted and the new `section` is added - - - - - -As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to "match up"** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a component from the tree. - - - -This is why you should not nest component function definitions. - -Here, the `MyTextField` component function is defined *inside* `MyComponent`: - - +As another example, if you use a prop `id` to identify each counter and pass in the `id` as a `key`: ```js -import { useState } from 'react'; - -export default function MyComponent() { - const [counter, setCounter] = useState(0); - - function MyTextField() { - const [text, setText] = useState(''); - - return ( - setText(e.target.value)} - /> - ); - } - - return ( - <> - - - - ); -} + ``` - - +React will *preserve* the state of each `Counter` across re-renders. This is great, for example, if you want to preserve the state of a comment input as the user types and then the comment re-appears even across re-renders. -Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You're rendering a *different* component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare component functions at the top level, and don't nest their definitions.** +### Resetting state with `key` is common when: {/*resetting-state-with-key-is-common-when*/} - +* You want to reset the input focus in a form +* You need to play an animation on re-render +* You want to reset the state of the child components -## Resetting state at the same position {/*resetting-state-at-the-same-position*/} +In general, **when you want to force a component and all its children to re-mount, use a `key` with a value that will change.** -By default, React preserves state of a component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component's state. Consider this app that lets two players keep track of their scores during each turn: +### When should you use `key`? {/*when-should-you-use-key*/} - - -```js -import { useState } from 'react'; +You should avoid using index as `key` in a list of items if the order of items can change. -export default function Scoreboard() { - const [isPlayerA, setIsPlayerA] = useState(true); - return ( -
- {isPlayerA ? ( - - ) : ( - - )} - -
- ); -} +In all other cases, [keys are useful](/learn/rendering-lists#rules-of-keys). Use keys to: -function Counter({ person }) { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); +* Tell React to preserve state of specific instances of the same component across re-renders. +* Tell React to detach and re-mount components (and reset their state). - let className = 'counter'; - if (hover) { - className += ' hover'; - } +## Recap {/*recap*/} - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{person}'s score: {score}

- -
- ); -} +* React associates state with a component's position in the render tree. +* When the same component is rendered at the same position, its state is preserved across re-renders. +* When a component is rendered at a different position, or a different component is rendered at the same position, React resets its state. +* You can control whether a component's state resets by changing the position of the component in the render tree, or by providing a `key` value. +```html +Parte 2 de 2: ``` -```css -h1 { - font-size: 18px; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; -} - -.hover { - background: #ffffd8; -} +```html +Parte 3 de 2: ``` -
- -Currently, when you change the player, the score is preserved. The two `Counter`s appear in the same position, so React sees them as *the same* `Counter` whose `person` prop has changed. - -But conceptually, in this app they should be two separate counters. They might appear in the same place in the UI, but one is a counter for Taylor, and another is a counter for Sarah. - -There are two ways to reset state when switching between them: - -1. Render components in different positions -2. Give each component an explicit identity with `key` - - -### Option 1: Rendering a component in different positions {/*option-1-rendering-a-component-in-different-positions*/} - -If you want these two `Counter`s to be independent, you can render them in two different positions: - - - ```js import { useState } from 'react'; -export default function Scoreboard() { - const [isPlayerA, setIsPlayerA] = useState(true); - return ( -
- {isPlayerA && - - } - {!isPlayerA && - - } - -
- ); -} - -function Counter({ person }) { - const [score, setScore] = useState(0); +function Counter({ person, score }) { const [hover, setHover] = useState(false); - let className = 'counter'; if (hover) { className += ' hover'; } - - return ( -
setHover(true)} - onPointerLeave={() => setHover(false)} - > -

{person}'s score: {score}

- -
- ); -} -``` - -```css -h1 { - font-size: 18px; -} - -.counter { - width: 100px; - text-align: center; - border: 1px solid gray; - border-radius: 4px; - padding: 20px; - margin: 0 20px 20px 0; -} - -.hover { - background: #ffffd8; -} ``` -
- -* Initially, `isPlayerA` is `true`. So the first position contains `Counter` state, and the second one is empty. -* When you click the "Next player" button the first position clears but the second one now contains a `Counter`. - - - - - -Initial state - - - - - -Clicking "next" - - - - - -Clicking "next" again - - - - - -Each `Counter`'s state gets destroyed each time it's removed from the DOM. This is why they reset every time you click the button. - -This solution is convenient when you only have a few independent components rendered in the same place. In this example, you only have two, so it's not a hassle to render both separately in the JSX. - -### Option 2: Resetting state with a key {/*option-2-resetting-state-with-a-key*/} - -There is also another, more generic, way to reset a component's state. - -You might have seen `key`s when [rendering lists.](/learn/rendering-lists#keeping-list-items-in-order-with-key) Keys aren't just for lists! You can use keys to make React distinguish between any components. By default, React uses order within the parent ("first counter", "second counter") to discern between components. But keys let you tell React that this is not just a *first* counter, or a *second* counter, but a specific counter--for example, *Taylor's* counter. This way, React will know *Taylor's* counter wherever it appears in the tree! - -In this example, the two ``s don't share state even though they appear in the same place in JSX: - - - ```js -import { useState } from 'react'; - -export default function Scoreboard() { - const [isPlayerA, setIsPlayerA] = useState(true); - return ( -
- {isPlayerA ? ( - - ) : ( - - )} - -
- ); -} - -function Counter({ person }) { - const [score, setScore] = useState(0); - const [hover, setHover] = useState(false); - - let className = 'counter'; - if (hover) { - className += ' hover'; - } - return (

{person}'s score: {score}

); @@ -999,7 +128,7 @@ h1 {
-Switching between Taylor and Sarah does not preserve the state. This is because **you gave them different `key`s:** +Alternar entre Taylor e Sarah não preserva o estado. Isso ocorre porque **você deu a elas diferentes `key`s:** ```js {isPlayerA ? ( @@ -1009,19 +138,19 @@ Switching between Taylor and Sarah does not preserve the state. This is because )} ``` -Specifying a `key` tells React to use the `key` itself as part of the position, instead of their order within the parent. This is why, even though you render them in the same place in JSX, React sees them as two different counters, and so they will never share state. Every time a counter appears on the screen, its state is created. Every time it is removed, its state is destroyed. Toggling between them resets their state over and over. +Especificar uma `key` diz ao React para usar a própria `key` como parte da posição, em vez de sua ordem dentro do pai. É por isso que, mesmo que você as renderize no mesmo lugar em JSX, o React as vê como dois contadores diferentes e, portanto, elas nunca compartilharão o estado. Toda vez que um contador aparece na tela, seu estado é criado. Toda vez que ele é removido, seu estado é destruído. Alternar entre elas redefine seu estado várias vezes. -Remember that keys are not globally unique. They only specify the position *within the parent*. +Lembre-se de que as chaves não são globalmente únicas. Elas especificam apenas a posição *dentro do pai*. -### Resetting a form with a key {/*resetting-a-form-with-a-key*/} +### Redefinindo um formulário com uma chave {/*resetting-a-form-with-a-key*/} -Resetting state with a key is particularly useful when dealing with forms. +Redefinir o estado com uma chave é particularmente útil ao lidar com formulários. -In this chat app, the `` component contains the text input state: +Neste aplicativo de bate-papo, o componente `` contém o estado da entrada de texto: @@ -1116,17 +245,17 @@ textarea { -Try entering something into the input, and then press "Alice" or "Bob" to choose a different recipient. You will notice that the input state is preserved because the `` is rendered at the same position in the tree. +Tente digitar algo na entrada e, em seguida, pressione "Alice" ou "Bob" para escolher um destinatário diferente. Você notará que o estado de entrada é preservado porque o `` é renderizado na mesma posição na árvore. -**In many apps, this may be the desired behavior, but not in a chat app!** You don't want to let the user send a message they already typed to a wrong person due to an accidental click. To fix it, add a `key`: +**Em muitos aplicativos, este pode ser o comportamento desejado, mas não em um aplicativo de bate-papo!** Você não quer permitir que o usuário envie uma mensagem que já digitou para uma pessoa errada devido a um clique acidental. Para corrigi-lo, adicione uma `key`: ```js ``` -This ensures that when you select a different recipient, the `Chat` component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them. +Isso garante que, ao selecionar um destinatário diferente, o componente `Chat` seja recriado do zero, incluindo qualquer estado na árvore abaixo dele. O React também recriará os elementos DOM em vez de reutilizá-los. -Now switching the recipient always clears the text field: +Agora, alternar o destinatário sempre limpa o campo de texto: @@ -1223,34 +352,32 @@ textarea { -#### Preserving state for removed components {/*preserving-state-for-removed-components*/} +#### Preservando o estado para componentes removidos {/*preserving-state-for-removed-components*/} -In a real chat app, you'd probably want to recover the input state when the user selects the previous recipient again. There are a few ways to keep the state "alive" for a component that's no longer visible: +Em um aplicativo de bate-papo real, você provavelmente gostaria de recuperar o estado de entrada quando o usuário selecionar o destinatário anterior novamente. Existem algumas maneiras de manter o estado "vivo" para um componente que não está mais visível: -- You could render _all_ chats instead of just the current one, but hide all the others with CSS. The chats would not get removed from the tree, so their local state would be preserved. This solution works great for simple UIs. But it can get very slow if the hidden trees are large and contain a lot of DOM nodes. -- You could [lift the state up](/learn/sharing-state-between-components) and hold the pending message for each recipient in the parent component. This way, when the child components get removed, it doesn't matter, because it's the parent that keeps the important information. This is the most common solution. -- You might also use a different source in addition to React state. For example, you probably want a message draft to persist even if the user accidentally closes the page. To implement this, you could have the `Chat` component initialize its state by reading from the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), and save the drafts there too. +- Você pode renderizar _todos_ os bate-papos em vez de apenas o atual, mas ocultar todos os outros com CSS. Os bate-papos não seriam removidos da árvore, então seu estado local seria preservado. Essa solução funciona muito bem para interfaces de usuário simples. Mas pode se tornar muito lento se as árvores ocultas forem grandes e contiverem muitos nós DOM. +- Você pode [elevar o estado](/learn/compartilhando-estado-entre-componentes) e manter a mensagem pendente para cada destinatário no componente pai. Dessa forma, quando os componentes filhos são removidos, não importa, porque é o pai que mantém as informações importantes. Esta é a solução mais comum. +- Você também pode usar uma fonte diferente além do estado do React. Por exemplo, você provavelmente deseja que um rascunho de mensagem persista mesmo que o usuário feche a página acidentalmente. Para implementar isso, você pode fazer com que o componente `Chat` inicialize seu estado lendo do [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) e salvar os rascunhos lá também. -No matter which strategy you pick, a chat _with Alice_ is conceptually distinct from a chat _with Bob_, so it makes sense to give a `key` to the `` tree based on the current recipient. +Não importa qual estratégia você escolher, um bate-papo _com Alice_ é conceitualmente distinto de um bate-papo _com Bob_, por isso faz sentido dar uma `key` à árvore `` com base no destinatário atual. -- React keeps state for as long as the same component is rendered at the same position. -- State is not kept in JSX tags. It's associated with the tree position in which you put that JSX. -- You can force a subtree to reset its state by giving it a different key. -- Don't nest component definitions, or you'll reset state by accident. +- O React mantém o estado enquanto o mesmo componente é renderizado na mesma posição. +- O estado não é mantido em tags JSX. Ele está associado à posição da árvore em que você colocou esse JSX. +- Você pode forçar uma subárvore a redefinir seu estado dando a ela uma chave diferente. +- Não aninhe definições de componentes ou você redefinirá o estado por acidente. - - -#### Fix disappearing input text {/*fix-disappearing-input-text*/} +#### Corrigir o desaparecimento do texto de entrada {/*fix-disappearing-input-text*/} -This example shows a message when you press the button. However, pressing the button also accidentally resets the input. Why does this happen? Fix it so that pressing the button does not reset the input text. +Este exemplo mostra uma mensagem quando você pressiona o botão. No entanto, pressionar o botão também redefine acidentalmente a entrada. Por que isso acontece? Corrija-o para que pressionar o botão não redefina o texto de entrada. @@ -1299,9 +426,9 @@ textarea { display: block; margin: 10px 0; } -The problem is that `Form` is rendered in different positions. In the `if` branch, it is the second child of the `
`, but in the `else` branch, it is the first child. Therefore, the component type in each position changes. The first position changes between holding a `p` and a `Form`, while the second position changes between holding a `Form` and a `button`. React resets the state every time the component type changes. +O problema é que `Form` é renderizado em posições diferentes. No ramo `if`, ele é o segundo filho do `
`, mas no ramo `else`, ele é o primeiro filho. Portanto, o tipo de componente em cada posição muda. A primeira posição muda entre conter um `

` e um `Form`, enquanto a segunda posição muda entre conter um `Form` e um `button`. O React redefine o estado toda vez que o tipo de componente muda. -The easiest solution is to unify the branches so that `Form` always renders in the same position: +A solução mais fácil é unificar os ramos para que `Form` sempre renderize na mesma posição: @@ -1346,8 +473,7 @@ textarea { display: block; margin: 10px 0; } - -Technically, you could also add `null` before `

` in the `else` branch to match the `if` branch structure: +Tecnicamente, você também pode adicionar `null` antes de `` no ramo `else` para corresponder à estrutura do ramo `if`: @@ -1395,19 +521,19 @@ textarea { display: block; margin: 10px 0; } -This way, `Form` is always the second child, so it stays in the same position and keeps its state. But this approach is much less obvious and introduces a risk that someone else will remove that `null`. +Dessa forma, o `Form` é sempre o segundo filho, então ele permanece na mesma posição e mantém seu estado. Mas essa abordagem é muito menos óbvia e introduz o risco de que outra pessoa remova esse `null`. -#### Swap two form fields {/*swap-two-form-fields*/} +#### Trocar dois campos de formulário {/*swap-two-form-fields*/} -This form lets you enter first and last name. It also has a checkbox controlling which field goes first. When you tick the checkbox, the "Last name" field will appear before the "First name" field. +Este formulário permite que você insira o primeiro e o último nome. Ele também possui uma caixa de seleção que controla qual campo vai primeiro. Quando você marca a caixa de seleção, o campo "Sobrenome" aparecerá antes do campo "Nome". -It almost works, but there is a bug. If you fill in the "First name" input and tick the checkbox, the text will stay in the first input (which is now "Last name"). Fix it so that the input text *also* moves when you reverse the order. +Funciona quase, mas há um erro. Se você preencher a entrada "Nome" e marcar a caixa de seleção, o texto permanecerá na primeira entrada (que agora é "Sobrenome"). Corrija-o para que o texto de entrada *também* se mova quando você inverter a ordem. -It seems like for these fields, their position within the parent is not enough. Is there some way to tell React how to match up the state between re-renders? +Parece que para esses campos, sua posição dentro do pai não é suficiente. Existe alguma maneira de dizer ao React como combinar o estado entre as renderizações? @@ -1471,7 +597,7 @@ label { display: block; margin: 10px 0; } -Give a `key` to both `` components in both `if` and `else` branches. This tells React how to "match up" the correct state for either `` even if their order within the parent changes: +Dê uma `key` aos dois componentes `` nos ramos `if` e `else`. Isso diz ao React como "combinar" o estado correto para `` mesmo que sua ordem dentro do pai mude: @@ -1529,15 +655,20 @@ function Field({ label }) { label { display: block; margin: 10px 0; } ``` + +```css +label { display: block; margin: 10px 0; } +``` + -#### Reset a detail form {/*reset-a-detail-form*/} +#### Reiniciar um formulário de detalhes {/*reset-a-detail-form*/} -This is an editable contact list. You can edit the selected contact's details and then either press "Save" to update it, or "Reset" to undo your changes. +Esta é uma lista de contatos editável. Você pode editar os detalhes do contato selecionado e, em seguida, pressionar "Salvar" para atualizá-lo, ou "Redefinir" para desfazer suas alterações. -When you select a different contact (for example, Alice), the state updates but the form keeps showing the previous contact's details. Fix it so that the form gets reset when the selected contact changes. +Quando você seleciona um contato diferente (por exemplo, Alice), o estado é atualizado, mas o formulário continua mostrando os detalhes do contato anterior. Corrija-o para que o formulário seja reiniciado quando o contato selecionado mudar. @@ -1689,7 +820,7 @@ button { -Give `key={selectedId}` to the `EditContact` component. This way, switching between different contacts will reset the form: +Dê `key={selectedId}` ao componente `EditContact`. Desta forma, a troca entre diferentes contatos reiniciará o formulário: @@ -1842,13 +973,13 @@ button { -#### Clear an image while it's loading {/*clear-an-image-while-its-loading*/} +#### Limpar uma imagem enquanto ela está carregando {/*clear-an-image-while-its-loading*/} -When you press "Next", the browser starts loading the next image. However, because it's displayed in the same `` tag, by default you would still see the previous image until the next one loads. This may be undesirable if it's important for the text to always match the image. Change it so that the moment you press "Next", the previous image immediately clears. +Quando você pressiona "Próximo", o navegador começa a carregar a próxima imagem. No entanto, como ela é exibida na mesma tag ``, por padrão, você ainda veria a imagem anterior até que a próxima carregue. Isso pode ser indesejável se for importante que o texto sempre corresponda à imagem. Mude-o para que, no momento em que você pressionar "Próximo", a imagem anterior seja limpa imediatamente. -Is there a way to tell React to re-create the DOM instead of reusing it? +Há alguma maneira de dizer ao React para recriar o DOM em vez de reutilizá-lo? @@ -1918,7 +1049,7 @@ img { width: 150px; height: 150px; } -You can provide a `key` to the `` tag. When that `key` changes, React will re-create the `` DOM node from scratch. This causes a brief flash when each image loads, so it's not something you'd want to do for every image in your app. But it makes sense if you want to ensure the image always matches the text. +Você pode fornecer uma `key` à tag ``. Quando essa `key` mudar, o React irá recriar o nó DOM `` do zero. Isso causa um breve flash quando cada imagem carrega, então não é algo que você gostaria de fazer para cada imagem em seu aplicativo. Mas faz sentido se você quiser garantir que a imagem sempre corresponda ao texto. @@ -1986,11 +1117,11 @@ img { width: 150px; height: 150px; } -#### Fix misplaced state in the list {/*fix-misplaced-state-in-the-list*/} +#### Corrigir o estado desalocado na lista {/*fix-misplaced-state-in-the-list*/} -In this list, each `Contact` has state that determines whether "Show email" has been pressed for it. Press "Show email" for Alice, and then tick the "Show in reverse order" checkbox. You will notice that it's _Taylor's_ email that is expanded now, but Alice's--which has moved to the bottom--appears collapsed. +Nesta lista, cada `Contact` tem estado que determina se "Mostrar e-mail" foi pressionado para ele. Pressione "Mostrar e-mail" para Alice e, em seguida, marque a caixa de seleção "Mostrar em ordem inversa". Você notará que é o e-mail de _Taylor_ que é expandido agora, mas o de Alice - que se moveu para baixo - aparece recolhido. -Fix it so that the expanded state is associated with each contact, regardless of the chosen ordering. +Corrija-o para que o estado expandido seja associado a cada contato, independentemente da ordenação escolhida. @@ -2016,7 +1147,7 @@ export default function ContactList() { setReverse(e.target.checked) }} />{' '} - Show in reverse order + Mostrar em ordem inversa
    {displayedContacts.map((contact, i) => @@ -2050,7 +1181,7 @@ export default function Contact({ contact }) { ); @@ -2080,16 +1211,16 @@ button { -The problem is that this example was using index as a `key`: +O problema é que este exemplo estava usando o índice como uma `key`: ```js {displayedContacts.map((contact, i) =>
  • ``` -However, you want the state to be associated with _each particular contact_. +No entanto, você quer que o estado seja associado a _cada contato em particular_. -Using the contact ID as a `key` instead fixes the issue: +Usar o ID do contato como uma `key` em vez disso corrige o problema: @@ -2115,7 +1246,7 @@ export default function ContactList() { setReverse(e.target.checked) }} />{' '} - Show in reverse order + Mostrar em ordem inversa
      {displayedContacts.map(contact => @@ -2149,7 +1280,7 @@ export default function Contact({ contact }) { ); @@ -2177,8 +1308,8 @@ button { -State is associated with the tree position. A `key` lets you specify a named position instead of relying on order. +O estado está associado à posição da árvore. Uma `key` permite que você especifique uma posição com nome em vez de depender da ordem. - + \ No newline at end of file