diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 70049e58e..bbe2d12b8 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -1,41 +1,41 @@ --- -title: Keeping Components Pure +title: Mantendo Componentes Puros --- -Some JavaScript functions are *pure.* Pure functions only perform a calculation and nothing more. By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. To get these benefits, though, there are a few rules you must follow. +Algumas funções JavaScript são *puras.* Funções puras apenas realizam um cálculo e nada mais. Ao escrever estritamente seus componentes apenas como funções puras, você pode evitar uma classe inteira de bugs desconcertantes e comportamentos imprevisíveis conforme sua base de código cresce. Para obter esses benefícios, no entanto, há algumas regras que você deve seguir. -* What purity is and how it helps you avoid bugs -* How to keep components pure by keeping changes out of the render phase -* How to use Strict Mode to find mistakes in your components +* O que é pureza e como ela ajuda você a evitar bugs +* Como manter componentes puros mantendo mudanças fora da fase de renderização +* Como usar o Modo Estrito para encontrar erros em seus componentes -## Purity: Components as formulas {/*purity-components-as-formulas*/} +## Pureza: Componentes como fórmulas {/*purity-components-as-formulas*/} -In computer science (and especially the world of functional programming), [a pure function](https://wikipedia.org/wiki/Pure_function) is a function with the following characteristics: +Na ciência da computação (e especialmente no mundo da programação funcional), [uma função pura](https://wikipedia.org/wiki/Pure_function) é uma função com as seguintes características: -* **It minds its own business.** It does not change any objects or variables that existed before it was called. -* **Same inputs, same output.** Given the same inputs, a pure function should always return the same result. +* **Ela cuida apenas dos seus próprios assuntos.** Ela não altera nenhum objeto ou variável que existia antes de ser chamada. +* **Mesmas entradas, mesma saída.** Dadas as mesmas entradas, uma função pura sempre deve retornar o mesmo resultado. -You might already be familiar with one example of pure functions: formulas in math. +Você pode já estar familiarizado com um exemplo de funções puras: fórmulas na matemática. -Consider this math formula: y = 2x. +Considere esta fórmula matemática: y = 2x. -If x = 2 then y = 4. Always. +Se x = 2 então y = 4. Sempre. -If x = 3 then y = 6. Always. +Se x = 3 então y = 6. Sempre. -If x = 3, y won't sometimes be 9 or –1 or 2.5 depending on the time of day or the state of the stock market. +Se x = 3, y não será às vezes 9 ou –1 ou 2.5 dependendo da hora do dia ou do estado do mercado de ações. -If y = 2x and x = 3, y will _always_ be 6. +Se y = 2x e x = 3, y será _sempre_ 6. -If we made this into a JavaScript function, it would look like this: +Se transformássemos isso em uma função JavaScript, ficaria assim: ```js function double(number) { @@ -43,9 +43,9 @@ function double(number) { } ``` -In the above example, `double` is a **pure function.** If you pass it `3`, it will return `6`. Always. +No exemplo acima, `double` é uma **função pura.** Se você passar `3` para ela, ela retornará `6`. Sempre. -React is designed around this concept. **React assumes that every component you write is a pure function.** This means that React components you write must always return the same JSX given the same inputs: +React é projetado em torno deste conceito. **React assume que todo componente que você escreve é uma função pura.** Isso significa que os componentes React que você escreve devem sempre retornar o mesmo JSX dadas as mesmas entradas: @@ -53,9 +53,9 @@ React is designed around this concept. **React assumes that every component you function Recipe({ drinkers }) { return (
    -
  1. Boil {drinkers} cups of water.
  2. -
  3. Add {drinkers} spoons of tea and {0.5 * drinkers} spoons of spice.
  4. -
  5. Add {0.5 * drinkers} cups of milk to boil and sugar to taste.
  6. +
  7. Ferva {drinkers} xícaras de água.
  8. +
  9. Adicione {drinkers} colheres de chá e {0.5 * drinkers} colheres de especiarias.
  10. +
  11. Adicione {0.5 * drinkers} xícaras de leite para ferver e açúcar a gosto.
); } @@ -63,10 +63,10 @@ function Recipe({ drinkers }) { export default function App() { return (
-

Spiced Chai Recipe

-

For two

+

Receita de Chai com Especiarias

+

Para dois

-

For a gathering

+

Para uma reunião

); @@ -75,21 +75,21 @@ export default function App() {
-When you pass `drinkers={2}` to `Recipe`, it will return JSX containing `2 cups of water`. Always. +Quando você passa `drinkers={2}` para `Recipe`, ela retornará JSX contendo `2 xícaras de água`. Sempre. -If you pass `drinkers={4}`, it will return JSX containing `4 cups of water`. Always. +Se você passar `drinkers={4}`, ela retornará JSX contendo `4 xícaras de água`. Sempre. -Just like a math formula. +Assim como uma fórmula matemática. -You could think of your components as recipes: if you follow them and don't introduce new ingredients during the cooking process, you will get the same dish every time. That "dish" is the JSX that the component serves to React to [render.](/learn/render-and-commit) +Você poderia pensar nos seus componentes como receitas: se você segui-las e não introduzir novos ingredientes durante o processo de cozimento, você obterá o mesmo prato toda vez. Esse "prato" é o JSX que o componente serve ao React para [renderizar.](/learn/render-and-commit) - + -## Side Effects: (un)intended consequences {/*side-effects-unintended-consequences*/} +## Efeitos colaterais: consequências (não)intencionais {/*side-effects-unintended-consequences*/} -React's rendering process must always be pure. Components should only *return* their JSX, and not *change* any objects or variables that existed before rendering—that would make them impure! +O processo de renderização do React deve sempre ser puro. Componentes devem apenas *retornar* seu JSX, e não *alterar* nenhum objeto ou variável que existia antes da renderização—isso os tornaria impuros! -Here is a component that breaks this rule: +Aqui está um componente que quebra esta regra: @@ -97,9 +97,9 @@ Here is a component that breaks this rule: let guest = 0; function Cup() { - // Bad: changing a preexisting variable! + // Ruim: alterando uma variável pré-existente! guest = guest + 1; - return

Tea cup for guest #{guest}

; + return

Xícara de chá para convidado #{guest}

; } export default function TeaSet() { @@ -115,17 +115,17 @@ export default function TeaSet() {
-This component is reading and writing a `guest` variable declared outside of it. This means that **calling this component multiple times will produce different JSX!** And what's more, if _other_ components read `guest`, they will produce different JSX, too, depending on when they were rendered! That's not predictable. +Este componente está lendo e escrevendo uma variável `guest` declarada fora dele. Isso significa que **chamar este componente múltiplas vezes produzirá JSX diferente!** E mais ainda, se _outros_ componentes lerem `guest`, eles também produzirão JSX diferente, dependendo de quando foram renderizados! Isso não é previsível. -Going back to our formula y = 2x, now even if x = 2, we cannot trust that y = 4. Our tests could fail, our users would be baffled, planes would fall out of the sky—you can see how this would lead to confusing bugs! +Voltando à nossa fórmula y = 2x, agora mesmo se x = 2, não podemos confiar que y = 4. Nossos testes poderiam falhar, nossos usuários ficariam perplexos, aviões cairiam do céu—você pode ver como isso levaria a bugs confusos! -You can fix this component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component): +Você pode corrigir este componente [passando `guest` como uma prop em vez disso](/learn/passing-props-to-a-component): ```js function Cup({ guest }) { - return

Tea cup for guest #{guest}

; + return

Xícara de chá para convidado #{guest}

; } export default function TeaSet() { @@ -141,37 +141,37 @@ export default function TeaSet() {
-Now your component is pure, as the JSX it returns only depends on the `guest` prop. +Agora seu componente é puro, pois o JSX que ele retorna depende apenas da prop `guest`. -In general, you should not expect your components to be rendered in any particular order. It doesn't matter if you call y = 2x before or after y = 5x: both formulas will resolve independently of each other. In the same way, each component should only "think for itself", and not attempt to coordinate with or depend upon others during rendering. Rendering is like a school exam: each component should calculate JSX on their own! +Em geral, você não deve esperar que seus componentes sejam renderizados em uma ordem específica. Não importa se você chamar y = 2x antes ou depois de y = 5x: ambas as fórmulas se resolverão independentemente uma da outra. Da mesma forma, cada componente deve apenas "pensar por si mesmo", e não tentar se coordenar com ou depender de outros durante a renderização. A renderização é como um exame escolar: cada componente deve calcular JSX por conta própria! -#### Detecting impure calculations with StrictMode {/*detecting-impure-calculations-with-strict-mode*/} +#### Detectando cálculos impuros com StrictMode {/*detecting-impure-calculations-with-strict-mode*/} -Although you might not have used them all yet, in React there are three kinds of inputs that you can read while rendering: [props](/learn/passing-props-to-a-component), [state](/learn/state-a-components-memory), and [context.](/learn/passing-data-deeply-with-context) You should always treat these inputs as read-only. +Embora você talvez ainda não tenha usado todos eles, no React existem três tipos de entradas que você pode ler durante a renderização: [props](/learn/passing-props-to-a-component), [state](/learn/state-a-components-memory), e [context.](/learn/passing-data-deeply-with-context) Você deve sempre tratar essas entradas como somente leitura. -When you want to *change* something in response to user input, you should [set state](/learn/state-a-components-memory) instead of writing to a variable. You should never change preexisting variables or objects while your component is rendering. +Quando você quiser *alterar* algo em resposta à entrada do usuário, você deve [definir state](/learn/state-a-components-memory) em vez de escrever em uma variável. Você nunca deve alterar variáveis ou objetos pré-existentes enquanto seu componente está renderizando. -React offers a "Strict Mode" in which it calls each component's function twice during development. **By calling the component functions twice, Strict Mode helps find components that break these rules.** +O React oferece um "Modo Estrito" no qual ele chama a função de cada componente duas vezes durante o desenvolvimento. **Ao chamar as funções dos componentes duas vezes, o Modo Estrito ajuda a encontrar componentes que quebram essas regras.** -Notice how the original example displayed "Guest #2", "Guest #4", and "Guest #6" instead of "Guest #1", "Guest #2", and "Guest #3". The original function was impure, so calling it twice broke it. But the fixed pure version works even if the function is called twice every time. **Pure functions only calculate, so calling them twice won't change anything**--just like calling `double(2)` twice doesn't change what's returned, and solving y = 2x twice doesn't change what y is. Same inputs, same outputs. Always. +Observe como o exemplo original exibiu "Convidado #2", "Convidado #4", e "Convidado #6" em vez de "Convidado #1", "Convidado #2", e "Convidado #3". A função original era impura, então chamá-la duas vezes a quebrou. Mas a versão pura corrigida funciona mesmo se a função for chamada duas vezes toda vez. **Funções puras apenas calculam, então chamá-las duas vezes não mudará nada**—assim como chamar `double(2)` duas vezes não muda o que é retornado, e resolver y = 2x duas vezes não muda o que y é. Mesmas entradas, mesmas saídas. Sempre. -Strict Mode has no effect in production, so it won't slow down the app for your users. To opt into Strict Mode, you can wrap your root component into ``. Some frameworks do this by default. +O Modo Estrito não tem efeito em produção, então não deixará o aplicativo mais lento para seus usuários. Para optar pelo Modo Estrito, você pode envolver seu componente raiz em ``. Alguns frameworks fazem isso por padrão. -### Local mutation: Your component's little secret {/*local-mutation-your-components-little-secret*/} +### Mutação local: O pequeno segredo do seu componente {/*local-mutation-your-components-little-secret*/} -In the above example, the problem was that the component changed a *preexisting* variable while rendering. This is often called a **"mutation"** to make it sound a bit scarier. Pure functions don't mutate variables outside of the function's scope or objects that were created before the call—that makes them impure! +No exemplo acima, o problema era que o componente alterou uma variável *pré-existente* durante a renderização. Isso é frequentemente chamado de **"mutação"** para soar um pouco mais assustador. Funções puras não mutam variáveis fora do escopo da função ou objetos que foram criados antes da chamada—isso as torna impuras! -However, **it's completely fine to change variables and objects that you've *just* created while rendering.** In this example, you create an `[]` array, assign it to a `cups` variable, and then `push` a dozen cups into it: +No entanto, **é perfeitamente normal alterar variáveis e objetos que você *acabou* de criar durante a renderização.** Neste exemplo, você cria um array `[]`, o atribui a uma variável `cups`, e então faz `push` de uma dúzia de xícaras nele: ```js function Cup({ guest }) { - return

Tea cup for guest #{guest}

; + return

Xícara de chá para convidado #{guest}

; } export default function TeaGathering() { @@ -185,59 +185,57 @@ export default function TeaGathering() {
-If the `cups` variable or the `[]` array were created outside the `TeaGathering` function, this would be a huge problem! You would be changing a *preexisting* object by pushing items into that array. +Se a variável `cups` ou o array `[]` fossem criados fora da função `TeaGathering`, isso seria um grande problema! Você estaria alterando um objeto *pré-existente* empurrando itens para esse array. -However, it's fine because you've created them *during the same render*, inside `TeaGathering`. No code outside of `TeaGathering` will ever know that this happened. This is called **"local mutation"**—it's like your component's little secret. +No entanto, está tudo bem porque você os criou *durante a mesma renderização*, dentro de `TeaGathering`. Nenhum código fora de `TeaGathering` jamais saberá que isso aconteceu. Isso é chamado de **"mutação local"**—é como o pequeno segredo do seu componente. -## Where you _can_ cause side effects {/*where-you-_can_-cause-side-effects*/} +## Onde você _pode_ causar efeitos colaterais {/*where-you-_can_-cause-side-effects*/} -While functional programming relies heavily on purity, at some point, somewhere, _something_ has to change. That's kind of the point of programming! These changes—updating the screen, starting an animation, changing the data—are called **side effects.** They're things that happen _"on the side"_, not during rendering. +Embora a programação funcional dependa muito da pureza, em algum ponto, em algum lugar, _alguma coisa_ tem que mudar. Esse é meio que o ponto da programação! Essas mudanças—atualizar a tela, iniciar uma animação, alterar os dados—são chamadas de **efeitos colaterais.** São coisas que acontecem _"ao lado"_, não durante a renderização. -In React, **side effects usually belong inside [event handlers.](/learn/responding-to-events)** Event handlers are functions that React runs when you perform some action—for example, when you click a button. Even though event handlers are defined *inside* your component, they don't run *during* rendering! **So event handlers don't need to be pure.** +No React, **efeitos colaterais geralmente pertencem dentro de [manipuladores de eventos.](/learn/responding-to-events)** Manipuladores de eventos são funções que o React executa quando você realiza alguma ação—por exemplo, quando você clica em um botão. Mesmo que os manipuladores de eventos sejam definidos *dentro* do seu componente, eles não executam *durante* a renderização! **Então os manipuladores de eventos não precisam ser puros.** -If you've exhausted all other options and can't find the right event handler for your side effect, you can still attach it to your returned JSX with a [`useEffect`](/reference/react/useEffect) call in your component. This tells React to execute it later, after rendering, when side effects are allowed. **However, this approach should be your last resort.** +Se você esgotou todas as outras opções e não consegue encontrar o manipulador de eventos correto para seu efeito colateral, você ainda pode anexá-lo ao seu JSX retornado com uma chamada [`useEffect`](/reference/react/useEffect) no seu componente. Isso diz ao React para executá-lo mais tarde, após a renderização, quando efeitos colaterais são permitidos. **No entanto, esta abordagem deve ser seu último recurso.** -When possible, try to express your logic with rendering alone. You'll be surprised how far this can take you! +Quando possível, tente expressar sua lógica apenas com renderização. Você ficará surpreso com o quão longe isso pode levá-lo! -#### Why does React care about purity? {/*why-does-react-care-about-purity*/} +#### Por que o React se importa com pureza? {/*why-does-react-care-about-purity*/} -Writing pure functions takes some habit and discipline. But it also unlocks marvelous opportunities: +Escrever funções puras exige algum hábito e disciplina. Mas também desbloqueiam oportunidades maravilhosas: -* Your components could run in a different environment—for example, on the server! Since they return the same result for the same inputs, one component can serve many user requests. -* You can improve performance by [skipping rendering](/reference/react/memo) components whose inputs have not changed. This is safe because pure functions always return the same results, so they are safe to cache. -* If some data changes in the middle of rendering a deep component tree, React can restart rendering without wasting time to finish the outdated render. Purity makes it safe to stop calculating at any time. +* Seus componentes poderiam executar em um ambiente diferente—por exemplo, no servidor! Como eles retornam o mesmo resultado para as mesmas entradas, um componente pode servir muitas solicitações de usuários. +* Você pode melhorar a performance [pulando a renderização](/reference/react/memo) de componentes cujas entradas não mudaram. Isso é seguro porque funções puras sempre retornam os mesmos resultados, então são seguras para cache. +* Se alguns dados mudarem no meio da renderização de uma árvore de componentes profunda, o React pode reiniciar a renderização sem desperdiçar tempo para terminar a renderização desatualizada. A pureza torna seguro parar de calcular a qualquer momento. -Every new React feature we're building takes advantage of purity. From data fetching to animations to performance, keeping components pure unlocks the power of the React paradigm. +Todo novo recurso do React que estamos construindo aproveita a pureza. Da busca de dados às animações à performance, manter componentes puros desbloqueiam o poder do paradigma React. -* A component must be pure, meaning: - * **It minds its own business.** It should not change any objects or variables that existed before rendering. - * **Same inputs, same output.** Given the same inputs, a component should always return the same JSX. -* Rendering can happen at any time, so components should not depend on each others' rendering sequence. -* You should not mutate any of the inputs that your components use for rendering. That includes props, state, and context. To update the screen, ["set" state](/learn/state-a-components-memory) instead of mutating preexisting objects. -* Strive to express your component's logic in the JSX you return. When you need to "change things", you'll usually want to do it in an event handler. As a last resort, you can `useEffect`. -* Writing pure functions takes a bit of practice, but it unlocks the power of React's paradigm. +* Um componente deve ser puro, significando: + * **Ele cuida apenas dos seus próprios assuntos.** Ele não deve alterar nenhum objeto ou variável que existia antes da renderização. + * **Mesmas entradas, mesma saída.** Dadas as mesmas entradas, um componente deve sempre retornar o mesmo JSX. +* A renderização pode acontecer a qualquer momento, então os componentes não devem depender da sequência de renderização uns dos outros. +* Você não deve mutar nenhuma das entradas que seus componentes usam para renderização. Isso inclui props, state, e context. Para atualizar a tela, ["defina" state](/learn/state-a-components-memory) em vez de mutar objetos pré-existentes. +* Esforce-se para expressar a lógica do seu componente no JSX que você retorna. Quando você precisar "mudar coisas", você geralmente vai querer fazer isso em um manipulador de eventos. Como último recurso, você pode usar `useEffect`. +* Escrever funções puras exige um pouco de prática, mas desbloqueiam o poder do paradigma do React. - - -#### Fix a broken clock {/*fix-a-broken-clock*/} +#### Conserte um relógio quebrado {/*fix-a-broken-clock*/} -This component tries to set the `

`'s CSS class to `"night"` during the time from midnight to six hours in the morning, and `"day"` at all other times. However, it doesn't work. Can you fix this component? +Este componente tenta definir a classe CSS do `

` para `"night"` durante o horário da meia-noite às seis horas da manhã, e `"day"` em todos os outros horários. No entanto, não funciona. Você pode consertar este componente? -You can verify whether your solution works by temporarily changing the computer's timezone. When the current time is between midnight and six in the morning, the clock should have inverted colors! +Você pode verificar se sua solução funciona mudando temporariamente o fuso horário do computador. Quando o horário atual estiver entre meia-noite e seis da manhã, o relógio deve ter cores invertidas! -Rendering is a *calculation*, it shouldn't try to "do" things. Can you express the same idea differently? +Renderização é um *cálculo*, ela não deveria tentar "fazer" coisas. Você pode expressar a mesma ideia de forma diferente? @@ -301,7 +299,7 @@ body > * { -You can fix this component by calculating the `className` and including it in the render output: +Você pode consertar este componente calculando o `className` e incluindo-o na saída da renderização: @@ -362,19 +360,19 @@ body > * { -In this example, the side effect (modifying the DOM) was not necessary at all. You only needed to return JSX. +Neste exemplo, o efeito colateral (modificar o DOM) não era necessário. Você só precisava retornar JSX. -#### Fix a broken profile {/*fix-a-broken-profile*/} +#### Conserte um perfil quebrado {/*fix-a-broken-profile*/} -Two `Profile` components are rendered side by side with different data. Press "Collapse" on the first profile, and then "Expand" it. You'll notice that both profiles now show the same person. This is a bug. +Dois componentes `Profile` são renderizados lado a lado com dados diferentes. Pressione "Recolher" no primeiro perfil, e então "Expandir". Você notará que ambos os perfis agora mostram a mesma pessoa. Isso é um bug. -Find the cause of the bug and fix it. +Encontre a causa do bug e conserte-o. -The buggy code is in `Profile.js`. Make sure you read it all from top to bottom! +O código com bug está em `Profile.js`. Certifique-se de lê-lo todo de cima a baixo! @@ -421,7 +419,7 @@ export default function Panel({ children }) { return (
{open && children}
@@ -475,9 +473,9 @@ h1 { margin: 5px; font-size: 18px; } -The problem is that the `Profile` component writes to a preexisting variable called `currentPerson`, and the `Header` and `Avatar` components read from it. This makes *all three of them* impure and difficult to predict. +O problema é que o componente `Profile` escreve em uma variável pré-existente chamada `currentPerson`, e os componentes `Header` e `Avatar` leem dela. Isso torna *todos os três* impuros e difíceis de prever. -To fix the bug, remove the `currentPerson` variable. Instead, pass all information from `Profile` to `Header` and `Avatar` via props. You'll need to add a `person` prop to both components and pass it all the way down. +Para consertar o bug, remova a variável `currentPerson`. Em vez disso, passe toda a informação de `Profile` para `Header` e `Avatar` via props. Você precisará adicionar uma prop `person` para ambos os componentes e passá-la por todo o caminho. @@ -519,7 +517,7 @@ export default function Panel({ children }) { return (
{open && children}
@@ -571,15 +569,15 @@ h1 { margin: 5px; font-size: 18px; }
-Remember that React does not guarantee that component functions will execute in any particular order, so you can't communicate between them by setting variables. All communication must happen through props. +Lembre-se de que o React não garante que as funções dos componentes executarão em uma ordem específica, então você não pode se comunicar entre eles definindo variáveis. Toda comunicação deve acontecer através de props.
-#### Fix a broken story tray {/*fix-a-broken-story-tray*/} +#### Conserte uma bandeja de histórias quebrada {/*fix-a-broken-story-tray*/} -The CEO of your company is asking you to add "stories" to your online clock app, and you can't say no. You've written a `StoryTray` component that accepts a list of `stories`, followed by a "Create Story" placeholder. +O CEO da sua empresa está pedindo para você adicionar "histórias" ao seu aplicativo de relógio online, e você não pode dizer não. Você escreveu um componente `StoryTray` que aceita uma lista de `stories`, seguida por um placeholder "Criar História". -You implemented the "Create Story" placeholder by pushing one more fake story at the end of the `stories` array that you receive as a prop. But for some reason, "Create Story" appears more than once. Fix the issue. +Você implementou o placeholder "Criar História" empurrando mais uma história falsa no final do array `stories` que você recebe como prop. Mas por alguma razão, "Criar História" aparece mais de uma vez. Conserte o problema. @@ -587,7 +585,7 @@ You implemented the "Create Story" placeholder by pushing one more fake story at export default function StoryTray({ stories }) { stories.push({ id: 'create', - label: 'Create Story' + label: 'Criar História' }); return ( @@ -607,16 +605,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; const initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "História do Ankit" }, + {id: 1, label: "História do Taylor" }, ]; export default function App() { const [stories, setStories] = useState([...initialStories]) const time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // HACK: Previne que a memória cresça para sempre enquanto você lê os docs. + // Estamos quebrando nossas próprias regras aqui. if (stories.length > 100) { stories.length = 100; } @@ -629,7 +627,7 @@ export default function App() { textAlign: 'center', }} > -

It is {time.toLocaleTimeString()} now.

+

Agora são {time.toLocaleTimeString()}.

); @@ -675,11 +673,11 @@ li { -Notice how whenever the clock updates, "Create Story" is added *twice*. This serves as a hint that we have a mutation during rendering--Strict Mode calls components twice to make these issues more noticeable. +Observe como sempre que o relógio atualiza, "Criar História" é adicionado *duas vezes*. Isso serve como uma dica de que temos uma mutação durante a renderização—o Modo Estrito chama componentes duas vezes para tornar esses problemas mais perceptíveis. -`StoryTray` function is not pure. By calling `push` on the received `stories` array (a prop!), it is mutating an object that was created *before* `StoryTray` started rendering. This makes it buggy and very difficult to predict. +A função `StoryTray` não é pura. Ao chamar `push` no array `stories` recebido (uma prop!), ela está mutando um objeto que foi criado *antes* de `StoryTray` começar a renderizar. Isso a torna com bugs e muito difícil de prever. -The simplest fix is to not touch the array at all, and render "Create Story" separately: +A correção mais simples é não tocar no array e renderizar "Criar História" separadamente: @@ -692,7 +690,7 @@ export default function StoryTray({ stories }) { {story.label} ))} -
  • Create Story
  • +
  • Criar História
  • ); } @@ -703,16 +701,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; const initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "História do Ankit" }, + {id: 1, label: "História do Taylor" }, ]; export default function App() { const [stories, setStories] = useState([...initialStories]) const time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // HACK: Previne que a memória cresça para sempre enquanto você lê os docs. + // Estamos quebrando nossas próprias regras aqui. if (stories.length > 100) { stories.length = 100; } @@ -725,7 +723,7 @@ export default function App() { textAlign: 'center', }} > -

    It is {time.toLocaleTimeString()} now.

    +

    Agora são {time.toLocaleTimeString()}.

    ); @@ -763,19 +761,19 @@ li {
    -Alternatively, you could create a _new_ array (by copying the existing one) before you push an item into it: +Alternativamente, você poderia criar um array _novo_ (copiando o existente) antes de empurrar um item nele: ```js src/StoryTray.js active export default function StoryTray({ stories }) { - // Copy the array! + // Copie o array! const storiesToDisplay = stories.slice(); - // Does not affect the original array: + // Não afeta o array original: storiesToDisplay.push({ id: 'create', - label: 'Create Story' + label: 'Criar História' }); return ( @@ -795,16 +793,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; const initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "História do Ankit" }, + {id: 1, label: "História do Taylor" }, ]; export default function App() { const [stories, setStories] = useState([...initialStories]) const time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // HACK: Previne que a memória cresça para sempre enquanto você lê os docs. + // Estamos quebrando nossas próprias regras aqui. if (stories.length > 100) { stories.length = 100; } @@ -817,7 +815,7 @@ export default function App() { textAlign: 'center', }} > -

    It is {time.toLocaleTimeString()} now.

    +

    Agora são {time.toLocaleTimeString()}.

    ); @@ -855,10 +853,10 @@ li {
    -This keeps your mutation local and your rendering function pure. However, you still need to be careful: for example, if you tried to change any of the array's existing items, you'd have to clone those items too. +Isso mantém sua mutação local e sua função de renderização pura. No entanto, você ainda precisa ter cuidado: por exemplo, se você tentasse alterar qualquer um dos itens existentes do array, você teria que clonar esses itens também. -It is useful to remember which operations on arrays mutate them, and which don't. For example, `push`, `pop`, `reverse`, and `sort` will mutate the original array, but `slice`, `filter`, and `map` will create a new one. +É útil lembrar quais operações em arrays os mutam, e quais não. Por exemplo, `push`, `pop`, `reverse`, e `sort` vão mutar o array original, mas `slice`, `filter`, e `map` vão criar um novo.
    - + \ No newline at end of file diff --git a/src/content/learn/setup.md b/src/content/learn/setup.md index 2c46ee148..578785497 100644 --- a/src/content/learn/setup.md +++ b/src/content/learn/setup.md @@ -1,28 +1,28 @@ --- -title: Setup +title: Configuração --- -React integrates with tools like editors, TypeScript, browser extensions, and compilers. This section will help you get your environment set up. +O React integra-se com ferramentas como editores, TypeScript, extensões de navegador e compiladores. Esta seção irá ajudá-lo a configurar seu ambiente. -## Editor Setup {/*editor-setup*/} +## Configuração do Editor {/*editor-setup*/} -See our [recommended editors](/learn/editor-setup) and learn how to set them up to work with React. +Veja nossos [editores recomendados](/learn/editor-setup) e aprenda como configurá-los para trabalhar com React. -## Using TypeScript {/*using-typescript*/} +## Usando TypeScript {/*using-typescript*/} -TypeScript is a popular way to add type definitions to JavaScript codebases. [Learn how to integrate TypeScript into your React projects](/learn/typescript). +TypeScript é uma forma popular de adicionar definições de tipo a bases de código JavaScript. [Aprenda como integrar TypeScript aos seus projetos React](/learn/typescript). -## React Developer Tools {/*react-developer-tools*/} +## Ferramentas de Desenvolvedor React {/*react-developer-tools*/} -React Developer Tools is a browser extension that can inspect React components, edit props and state, and identify performance problems. Learn how to install it [here](learn/react-developer-tools). +React Developer Tools é uma extensão de navegador que pode inspecionar componentes React, editar props e estado, e identificar problemas de performance. Aprenda como instalá-la [aqui](learn/react-developer-tools). -## React Compiler {/*react-compiler*/} +## Compilador React {/*react-compiler*/} -React Compiler is a tool that automatically optimizes your React app. [Learn more](/learn/react-compiler). +O Compilador React é uma ferramenta que otimiza automaticamente sua aplicação React. [Saiba mais](/learn/react-compiler). -## Next steps {/*next-steps*/} +## Próximos passos {/*next-steps*/} -Head to the [Quick Start](/learn) guide for a tour of the most important React concepts you will encounter every day. +Vá para o guia [Início Rápido](/learn) para um tour dos conceitos mais importantes do React que você encontrará todos os dias. \ No newline at end of file diff --git a/src/content/learn/updating-arrays-in-state.md b/src/content/learn/updating-arrays-in-state.md index 61e4f4e2d..a9e7f888d 100644 --- a/src/content/learn/updating-arrays-in-state.md +++ b/src/content/learn/updating-arrays-in-state.md @@ -1,52 +1,52 @@ --- -title: Updating Arrays in State +title: Atualizando Arrays no Estado --- -Arrays are mutable in JavaScript, but you should treat them as immutable when you store them in state. Just like with objects, when you want to update an array stored in state, you need to create a new one (or make a copy of an existing one), and then set state to use the new array. +Arrays são mutáveis em JavaScript, mas você deve tratá-los como imutáveis quando os armazena no estado. Assim como com objetos, quando você quer atualizar um array armazenado no estado, você precisa criar um novo (ou fazer uma cópia de um existente), e então definir o estado para usar o novo array. -- How to add, remove, or change items in an array in React state -- How to update an object inside of an array -- How to make array copying less repetitive with Immer +- Como adicionar, remover ou alterar itens em um array no estado do React +- Como atualizar um objeto dentro de um array +- Como tornar a cópia de arrays menos repetitiva com Immer -## Updating arrays without mutation {/*updating-arrays-without-mutation*/} +## Atualizando arrays sem mutação {/*updating-arrays-without-mutation*/} -In JavaScript, arrays are just another kind of object. [Like with objects](/learn/updating-objects-in-state), **you should treat arrays in React state as read-only.** This means that you shouldn't reassign items inside an array like `arr[0] = 'bird'`, and you also shouldn't use methods that mutate the array, such as `push()` and `pop()`. +Em JavaScript, arrays são apenas outro tipo de objeto. [Assim como com objetos](/learn/updating-objects-in-state), **você deve tratar arrays no estado do React como somente leitura.** Isso significa que você não deve reatribuir itens dentro de um array como `arr[0] = 'bird'`, e também não deve usar métodos que mutem o array, como `push()` e `pop()`. -Instead, every time you want to update an array, you'll want to pass a *new* array to your state setting function. To do that, you can create a new array from the original array in your state by calling its non-mutating methods like `filter()` and `map()`. Then you can set your state to the resulting new array. +Em vez disso, toda vez que você quiser atualizar um array, você vai querer passar um *novo* array para sua função de definição de estado. Para fazer isso, você pode criar um novo array a partir do array original em seu estado chamando seus métodos não-mutantes como `filter()` e `map()`. Então você pode definir seu estado para o novo array resultante. -Here is a reference table of common array operations. When dealing with arrays inside React state, you will need to avoid the methods in the left column, and instead prefer the methods in the right column: +Aqui está uma tabela de referência de operações comuns de array. Ao lidar com arrays dentro do estado do React, você precisará evitar os métodos na coluna da esquerda, e em vez disso preferir os métodos na coluna da direita: -| | avoid (mutates the array) | prefer (returns a new array) | -| --------- | ----------------------------------- | ------------------------------------------------------------------- | -| adding | `push`, `unshift` | `concat`, `[...arr]` spread syntax ([example](#adding-to-an-array)) | -| removing | `pop`, `shift`, `splice` | `filter`, `slice` ([example](#removing-from-an-array)) | -| replacing | `splice`, `arr[i] = ...` assignment | `map` ([example](#replacing-items-in-an-array)) | -| sorting | `reverse`, `sort` | copy the array first ([example](#making-other-changes-to-an-array)) | +| | evitar (muta o array) | preferir (retorna um novo array) | +| --------- | ----------------------------------- | ----------------------------------------------------------------------- | +| adicionar | `push`, `unshift` | `concat`, `[...arr]` sintaxe spread ([exemplo](#adding-to-an-array)) | +| remover | `pop`, `shift`, `splice` | `filter`, `slice` ([exemplo](#removing-from-an-array)) | +| substituir| `splice`, `arr[i] = ...` atribuição | `map` ([exemplo](#replacing-items-in-an-array)) | +| ordenar | `reverse`, `sort` | copie o array primeiro ([exemplo](#making-other-changes-to-an-array)) | -Alternatively, you can [use Immer](#write-concise-update-logic-with-immer) which lets you use methods from both columns. +Alternativamente, você pode [usar Immer](#write-concise-update-logic-with-immer) que permite usar métodos de ambas as colunas. -Unfortunately, [`slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) and [`splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) are named similarly but are very different: +Infelizmente, [`slice`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) e [`splice`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) têm nomes similares mas são muito diferentes: -* `slice` lets you copy an array or a part of it. -* `splice` **mutates** the array (to insert or delete items). +* `slice` permite copiar um array ou uma parte dele. +* `splice` **muta** o array (para inserir ou deletar itens). -In React, you will be using `slice` (no `p`!) a lot more often because you don't want to mutate objects or arrays in state. [Updating Objects](/learn/updating-objects-in-state) explains what mutation is and why it's not recommended for state. +No React, você estará usando `slice` (sem `p`!) muito mais frequentemente porque você não quer mutar objetos ou arrays no estado. [Atualizando Objetos](/learn/updating-objects-in-state) explica o que é mutação e por que não é recomendado para o estado. -### Adding to an array {/*adding-to-an-array*/} +### Adicionando a um array {/*adding-to-an-array*/} -`push()` will mutate an array, which you don't want: +`push()` vai mutar um array, o que você não quer: @@ -61,7 +61,7 @@ export default function List() { return ( <> -

    Inspiring sculptors:

    +

    Escultores inspiradores:

    setName(e.target.value)} @@ -71,7 +71,7 @@ export default function List() { id: nextId++, name: name, }); - }}>Add + }}>Adicionar
      {artists.map(artist => (
    • {artist.name}
    • @@ -88,18 +88,18 @@ button { margin-left: 5px; } -Instead, create a *new* array which contains the existing items *and* a new item at the end. There are multiple ways to do this, but the easiest one is to use the `...` [array spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_array_literals) syntax: +Em vez disso, crie um *novo* array que contém os itens existentes *e* um novo item no final. Há múltiplas maneiras de fazer isso, mas a mais fácil é usar a sintaxe `...` [array spread](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_em_literais_de_array): ```js -setArtists( // Replace the state - [ // with a new array - ...artists, // that contains all the old items - { id: nextId++, name: name } // and one new item at the end +setArtists( // Substitui o estado + [ // com um novo array + ...artists, // que contém todos os itens antigos + { id: nextId++, name: name } // e um novo item no final ] ); ``` -Now it works correctly: +Agora funciona corretamente: @@ -114,7 +114,7 @@ export default function List() { return ( <> -

      Inspiring sculptors:

      +

      Escultores inspiradores:

      setName(e.target.value)} @@ -124,7 +124,7 @@ export default function List() { ...artists, { id: nextId++, name: name } ]); - }}>Add + }}>Adicionar
        {artists.map(artist => (
      • {artist.name}
      • @@ -141,20 +141,20 @@ button { margin-left: 5px; } -The array spread syntax also lets you prepend an item by placing it *before* the original `...artists`: +A sintaxe array spread também permite que você adicione um item no início colocando-o *antes* do `...artists` original: ```js setArtists([ { id: nextId++, name: name }, - ...artists // Put old items at the end + ...artists // Coloca itens antigos no final ]); ``` -In this way, spread can do the job of both `push()` by adding to the end of an array and `unshift()` by adding to the beginning of an array. Try it in the sandbox above! +Dessa forma, spread pode fazer o trabalho tanto de `push()` adicionando ao final de um array quanto de `unshift()` adicionando ao início de um array. Experimente no sandbox acima! -### Removing from an array {/*removing-from-an-array*/} +### Removendo de um array {/*removing-from-an-array*/} -The easiest way to remove an item from an array is to *filter it out*. In other words, you will produce a new array that will not contain that item. To do this, use the `filter` method, for example: +A maneira mais fácil de remover um item de um array é *filtrá-lo*. Em outras palavras, você vai produzir um novo array que não conterá esse item. Para fazer isso, use o método `filter`, por exemplo: @@ -174,7 +174,7 @@ export default function List() { return ( <> -

        Inspiring sculptors:

        +

        Escultores inspiradores:

          {artists.map(artist => (
        • @@ -186,7 +186,7 @@ export default function List() { ) ); }}> - Delete + Deletar
        • ))} @@ -198,7 +198,7 @@ export default function List() { -Click the "Delete" button a few times, and look at its click handler. +Clique no botão "Deletar" algumas vezes, e observe seu manipulador de clique. ```js setArtists( @@ -206,13 +206,13 @@ setArtists( ); ``` -Here, `artists.filter(a => a.id !== artist.id)` means "create an array that consists of those `artists` whose IDs are different from `artist.id`". In other words, each artist's "Delete" button will filter _that_ artist out of the array, and then request a re-render with the resulting array. Note that `filter` does not modify the original array. +Aqui, `artists.filter(a => a.id !== artist.id)` significa "criar um array que consiste naqueles `artists` cujos IDs são diferentes de `artist.id`". Em outras palavras, o botão "Deletar" de cada artista vai filtrar _aquele_ artista do array, e então solicitar uma re-renderização com o array resultante. Note que `filter` não modifica o array original. -### Transforming an array {/*transforming-an-array*/} +### Transformando um array {/*transforming-an-array*/} -If you want to change some or all items of the array, you can use `map()` to create a **new** array. The function you will pass to `map` can decide what to do with each item, based on its data or its index (or both). +Se você quiser alterar alguns ou todos os itens do array, você pode usar `map()` para criar um **novo** array. A função que você passará para `map` pode decidir o que fazer com cada item, baseado em seus dados ou seu índice (ou ambos). -In this example, an array holds coordinates of two circles and a square. When you press the button, it moves only the circles down by 50 pixels. It does this by producing a new array of data using `map()`: +Neste exemplo, um array armazena coordenadas de dois círculos e um quadrado. Quando você pressiona o botão, ele move apenas os círculos 50 pixels para baixo. Ele faz isso produzindo um novo array de dados usando `map()`: @@ -233,24 +233,24 @@ export default function ShapeEditor() { function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { - // No change + // Sem mudança return shape; } else { - // Return a new circle 50px below + // Retorna um novo círculo 50px abaixo return { ...shape, y: shape.y + 50, }; } }); - // Re-render with the new array + // Re-renderiza com o novo array setShapes(nextShapes); } return ( <> {shapes.map(shape => (
          -### Replacing items in an array {/*replacing-items-in-an-array*/} +### Substituindo itens em um array {/*replacing-items-in-an-array*/} -It is particularly common to want to replace one or more items in an array. Assignments like `arr[0] = 'bird'` are mutating the original array, so instead you'll want to use `map` for this as well. +É particularmente comum querer substituir um ou mais itens em um array. Atribuições como `arr[0] = 'bird'` estão mutando o array original, então em vez disso você vai querer usar `map` para isso também. -To replace an item, create a new array with `map`. Inside your `map` call, you will receive the item index as the second argument. Use it to decide whether to return the original item (the first argument) or something else: +Para substituir um item, crie um novo array com `map`. Dentro de sua chamada `map`, você receberá o índice do item como segundo argumento. Use-o para decidir se deve retornar o item original (o primeiro argumento) ou algo diferente: @@ -301,10 +301,10 @@ export default function CounterList() { function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { - // Increment the clicked counter + // Incrementa o contador clicado return c + 1; } else { - // The rest haven't changed + // O resto não mudou return c; } }); @@ -332,11 +332,11 @@ button { margin: 5px; } -### Inserting into an array {/*inserting-into-an-array*/} +### Inserindo em um array {/*inserting-into-an-array*/} -Sometimes, you may want to insert an item at a particular position that's neither at the beginning nor at the end. To do this, you can use the `...` array spread syntax together with the `slice()` method. The `slice()` method lets you cut a "slice" of the array. To insert an item, you will create an array that spreads the slice _before_ the insertion point, then the new item, and then the rest of the original array. +Às vezes, você pode querer inserir um item em uma posição particular que não seja nem no início nem no final. Para fazer isso, você pode usar a sintaxe `...` array spread junto com o método `slice()`. O método `slice()` permite cortar uma "fatia" do array. Para inserir um item, você criará um array que espalha a fatia _antes_ do ponto de inserção, então o novo item, e então o resto do array original. -In this example, the Insert button always inserts at the index `1`: +Neste exemplo, o botão Inserir sempre insere no índice `1`: @@ -357,13 +357,13 @@ export default function List() { ); function handleClick() { - const insertAt = 1; // Could be any index + const insertAt = 1; // Pode ser qualquer índice const nextArtists = [ - // Items before the insertion point: + // Itens antes do ponto de inserção: ...artists.slice(0, insertAt), - // New item: + // Novo item: { id: nextId++, name: name }, - // Items after the insertion point: + // Itens depois do ponto de inserção: ...artists.slice(insertAt) ]; setArtists(nextArtists); @@ -372,13 +372,13 @@ export default function List() { return ( <> -

          Inspiring sculptors:

          +

          Escultores inspiradores:

          setName(e.target.value)} />
            {artists.map(artist => ( @@ -396,13 +396,13 @@ button { margin-left: 5px; } -### Making other changes to an array {/*making-other-changes-to-an-array*/} +### Fazendo outras mudanças em um array {/*making-other-changes-to-an-array*/} -There are some things you can't do with the spread syntax and non-mutating methods like `map()` and `filter()` alone. For example, you may want to reverse or sort an array. The JavaScript `reverse()` and `sort()` methods are mutating the original array, so you can't use them directly. +Há algumas coisas que você não pode fazer apenas com a sintaxe spread e métodos não-mutantes como `map()` e `filter()`. Por exemplo, você pode querer reverter ou ordenar um array. Os métodos JavaScript `reverse()` e `sort()` estão mutando o array original, então você não pode usá-los diretamente. -**However, you can copy the array first, and then make changes to it.** +**No entanto, você pode copiar o array primeiro, e então fazer mudanças nele.** -For example: +Por exemplo: @@ -427,7 +427,7 @@ export default function List() { return ( <>
              {list.map(artwork => ( @@ -441,25 +441,25 @@ export default function List() { -Here, you use the `[...list]` spread syntax to create a copy of the original array first. Now that you have a copy, you can use mutating methods like `nextList.reverse()` or `nextList.sort()`, or even assign individual items with `nextList[0] = "something"`. +Aqui, você usa a sintaxe spread `[...list]` para criar uma cópia do array original primeiro. Agora que você tem uma cópia, você pode usar métodos mutantes como `nextList.reverse()` ou `nextList.sort()`, ou até mesmo atribuir itens individuais com `nextList[0] = "algo"`. -However, **even if you copy an array, you can't mutate existing items _inside_ of it directly.** This is because copying is shallow--the new array will contain the same items as the original one. So if you modify an object inside the copied array, you are mutating the existing state. For example, code like this is a problem. +No entanto, **mesmo se você copiar um array, você não pode mutar itens existentes _dentro_ dele diretamente.** Isso é porque a cópia é superficial--o novo array conterá os mesmos itens que o original. Então se você modificar um objeto dentro do array copiado, você está mutando o estado existente. Por exemplo, código como este é um problema. ```js const nextList = [...list]; -nextList[0].seen = true; // Problem: mutates list[0] +nextList[0].seen = true; // Problema: muta list[0] setList(nextList); ``` -Although `nextList` and `list` are two different arrays, **`nextList[0]` and `list[0]` point to the same object.** So by changing `nextList[0].seen`, you are also changing `list[0].seen`. This is a state mutation, which you should avoid! You can solve this issue in a similar way to [updating nested JavaScript objects](/learn/updating-objects-in-state#updating-a-nested-object)--by copying individual items you want to change instead of mutating them. Here's how. +Embora `nextList` e `list` sejam dois arrays diferentes, **`nextList[0]` e `list[0]` apontam para o mesmo objeto.** Então ao mudar `nextList[0].seen`, você também está mudando `list[0].seen`. Esta é uma mutação de estado, que você deve evitar! Você pode resolver este problema de forma similar a [atualizar objetos JavaScript aninhados](/learn/updating-objects-in-state#updating-a-nested-object)--copiando itens individuais que você quer mudar em vez de mutá-los. Veja como. -## Updating objects inside arrays {/*updating-objects-inside-arrays*/} +## Atualizando objetos dentro de arrays {/*updating-objects-inside-arrays*/} -Objects are not _really_ located "inside" arrays. They might appear to be "inside" in code, but each object in an array is a separate value, to which the array "points". This is why you need to be careful when changing nested fields like `list[0]`. Another person's artwork list may point to the same element of the array! +Objetos não estão _realmente_ localizados "dentro" de arrays. Eles podem parecer estar "dentro" no código, mas cada objeto em um array é um valor separado, para o qual o array "aponta". É por isso que você precisa ter cuidado ao mudar campos aninhados como `list[0]`. A lista de obras de arte de outra pessoa pode apontar para o mesmo elemento do array! -**When updating nested state, you need to create copies from the point where you want to update, and all the way up to the top level.** Let's see how this works. +**Ao atualizar estado aninhado, você precisa criar cópias do ponto onde você quer atualizar, e todo o caminho até o nível superior.** Vamos ver como isso funciona. -In this example, two separate artwork lists have the same initial state. They are supposed to be isolated, but because of a mutation, their state is accidentally shared, and checking a box in one list affects the other list: +Neste exemplo, duas listas de obras de arte separadas têm o mesmo estado inicial. Elas deveriam estar isoladas, mas por causa de uma mutação, seu estado é acidentalmente compartilhado, e marcar uma caixa em uma lista afeta a outra lista: @@ -499,12 +499,12 @@ export default function BucketList() { return ( <> -

              Art Bucket List

              -

              My list of art to see:

              +

              Lista de Arte

              +

              Minha lista de arte para ver:

              -

              Your list of art to see:

              +

              Sua lista de arte para ver:

              @@ -539,34 +539,34 @@ function ItemList({ artworks, onToggle }) {
              -The problem is in code like this: +O problema está no código como este: ```js const myNextList = [...myList]; const artwork = myNextList.find(a => a.id === artworkId); -artwork.seen = nextSeen; // Problem: mutates an existing item +artwork.seen = nextSeen; // Problema: muta um item existente setMyList(myNextList); ``` -Although the `myNextList` array itself is new, the *items themselves* are the same as in the original `myList` array. So changing `artwork.seen` changes the *original* artwork item. That artwork item is also in `yourList`, which causes the bug. Bugs like this can be difficult to think about, but thankfully they disappear if you avoid mutating state. +Embora o array `myNextList` em si seja novo, os *itens em si* são os mesmos que no array `myList` original. Então mudar `artwork.seen` muda o item de obra de arte *original*. Esse item de obra de arte também está em `yourList`, o que causa o bug. Bugs como este podem ser difíceis de pensar, mas felizmente eles desaparecem se você evitar mutar o estado. -**You can use `map` to substitute an old item with its updated version without mutation.** +**Você pode usar `map` para substituir um item antigo por sua versão atualizada sem mutação.** ```js setMyList(myList.map(artwork => { if (artwork.id === artworkId) { - // Create a *new* object with changes + // Criar um *novo* objeto com mudanças return { ...artwork, seen: nextSeen }; } else { - // No changes + // Sem mudanças return artwork; } })); ``` -Here, `...` is the object spread syntax used to [create a copy of an object.](/learn/updating-objects-in-state#copying-objects-with-the-spread-syntax) +Aqui, `...` é a sintaxe object spread usada para [criar uma cópia de um objeto.](/learn/updating-objects-in-state#copying-objects-with-the-spread-syntax) -With this approach, none of the existing state items are being mutated, and the bug is fixed: +Com esta abordagem, nenhum dos itens de estado existentes está sendo mutado, e o bug é corrigido: @@ -589,10 +589,10 @@ export default function BucketList() { function handleToggleMyList(artworkId, nextSeen) { setMyList(myList.map(artwork => { if (artwork.id === artworkId) { - // Create a *new* object with changes + // Criar um *novo* objeto com mudanças return { ...artwork, seen: nextSeen }; } else { - // No changes + // Sem mudanças return artwork; } })); @@ -601,10 +601,10 @@ export default function BucketList() { function handleToggleYourList(artworkId, nextSeen) { setYourList(yourList.map(artwork => { if (artwork.id === artworkId) { - // Create a *new* object with changes + // Criar um *novo* objeto com mudanças return { ...artwork, seen: nextSeen }; } else { - // No changes + // Sem mudanças return artwork; } })); @@ -612,12 +612,12 @@ export default function BucketList() { return ( <> -

              Art Bucket List

              -

              My list of art to see:

              +

              Lista de Arte

              +

              Minha lista de arte para ver:

              -

              Your list of art to see:

              +

              Sua lista de arte para ver:

              @@ -652,16 +652,16 @@ function ItemList({ artworks, onToggle }) {
              -In general, **you should only mutate objects that you have just created.** If you were inserting a *new* artwork, you could mutate it, but if you're dealing with something that's already in state, you need to make a copy. +Em geral, **você deve apenas mutar objetos que você acabou de criar.** Se você estivesse inserindo uma *nova* obra de arte, você poderia mutá-la, mas se você está lidando com algo que já está no estado, você precisa fazer uma cópia. -### Write concise update logic with Immer {/*write-concise-update-logic-with-immer*/} +### Escreva lógica de atualização concisa com Immer {/*write-concise-update-logic-with-immer*/} -Updating nested arrays without mutation can get a little bit repetitive. [Just as with objects](/learn/updating-objects-in-state#write-concise-update-logic-with-immer): +Atualizar arrays aninhados sem mutação pode ficar um pouco repetitivo. [Assim como com objetos](/learn/updating-objects-in-state#write-concise-update-logic-with-immer): -- Generally, you shouldn't need to update state more than a couple of levels deep. If your state objects are very deep, you might want to [restructure them differently](/learn/choosing-the-state-structure#avoid-deeply-nested-state) so that they are flat. -- If you don't want to change your state structure, you might prefer to use [Immer](https://github.com/immerjs/use-immer), which lets you write using the convenient but mutating syntax and takes care of producing the copies for you. +- Geralmente, você não deveria precisar atualizar o estado mais do que alguns níveis de profundidade. Se seus objetos de estado são muito profundos, você pode querer [reestruturá-los de forma diferente](/learn/choosing-the-state-structure#avoid-deeply-nested-state) para que sejam planos. +- Se você não quer mudar sua estrutura de estado, você pode preferir usar [Immer](https://github.com/immerjs/use-immer), que permite escrever usando a sintaxe conveniente mas mutante e cuida de produzir as cópias para você. -Here is the Art Bucket List example rewritten with Immer: +Aqui está o exemplo da Lista de Arte reescrito com Immer: @@ -704,12 +704,12 @@ export default function BucketList() { return ( <> -

              Art Bucket List

              -

              My list of art to see:

              +

              Lista de Arte

              +

              Minha lista de arte para ver:

              -

              Your list of art to see:

              +

              Sua lista de arte para ver:

              @@ -762,7 +762,7 @@ function ItemList({ artworks, onToggle }) {
              -Note how with Immer, **mutation like `artwork.seen = nextSeen` is now okay:** +Note como com Immer, **mutação como `artwork.seen = nextSeen` agora está ok:** ```js updateMyTodos(draft => { @@ -771,17 +771,17 @@ updateMyTodos(draft => { }); ``` -This is because you're not mutating the _original_ state, but you're mutating a special `draft` object provided by Immer. Similarly, you can apply mutating methods like `push()` and `pop()` to the content of the `draft`. +Isso é porque você não está mutando o estado _original_, mas você está mutando um objeto `draft` especial fornecido pelo Immer. Similarmente, você pode aplicar métodos mutantes como `push()` e `pop()` ao conteúdo do `draft`. -Behind the scenes, Immer always constructs the next state from scratch according to the changes that you've done to the `draft`. This keeps your event handlers very concise without ever mutating state. +Por trás dos panos, Immer sempre constrói o próximo estado do zero de acordo com as mudanças que você fez no `draft`. Isso mantém seus manipuladores de evento muito concisos sem nunca mutar o estado. -- You can put arrays into state, but you can't change them. -- Instead of mutating an array, create a *new* version of it, and update the state to it. -- You can use the `[...arr, newItem]` array spread syntax to create arrays with new items. -- You can use `filter()` and `map()` to create new arrays with filtered or transformed items. -- You can use Immer to keep your code concise. +- Você pode colocar arrays no estado, mas você não pode mudá-los. +- Em vez de mutar um array, crie uma *nova* versão dele, e atualize o estado para ela. +- Você pode usar a sintaxe `[...arr, newItem]` array spread para criar arrays com novos itens. +- Você pode usar `filter()` e `map()` para criar novos arrays com itens filtrados ou transformados. +- Você pode usar Immer para manter seu código conciso. @@ -789,9 +789,9 @@ Behind the scenes, Immer always constructs the next state from scratch according -#### Update an item in the shopping cart {/*update-an-item-in-the-shopping-cart*/} +#### Atualizar um item no carrinho de compras {/*update-an-item-in-the-shopping-cart*/} -Fill in the `handleIncreaseClick` logic so that pressing "+" increases the corresponding number: +Preencha a lógica de `handleIncreaseClick` para que pressionar "+" aumente o número correspondente: @@ -804,11 +804,11 @@ const initialProducts = [{ count: 1, }, { id: 1, - name: 'Cheese', + name: 'Queijo', count: 5, }, { id: 2, - name: 'Spaghetti', + name: 'Espaguete', count: 2, }]; @@ -849,7 +849,7 @@ button { margin: 5px; } -You can use the `map` function to create a new array, and then use the `...` object spread syntax to create a copy of the changed object for the new array: +Você pode usar a função `map` para criar um novo array, e então usar a sintaxe `...` object spread para criar uma cópia do objeto alterado para o novo array: @@ -862,11 +862,11 @@ const initialProducts = [{ count: 1, }, { id: 1, - name: 'Cheese', + name: 'Queijo', count: 5, }, { id: 2, - name: 'Spaghetti', + name: 'Espaguete', count: 2, }]; @@ -916,9 +916,9 @@ button { margin: 5px; } -#### Remove an item from the shopping cart {/*remove-an-item-from-the-shopping-cart*/} +#### Remover um item do carrinho de compras {/*remove-an-item-from-the-shopping-cart*/} -This shopping cart has a working "+" button, but the "–" button doesn't do anything. You need to add an event handler to it so that pressing it decreases the `count` of the corresponding product. If you press "–" when the count is 1, the product should automatically get removed from the cart. Make sure it never shows 0. +Este carrinho de compras tem um botão "+" funcionando, mas o botão "–" não faz nada. Você precisa adicionar um manipulador de evento a ele para que pressioná-lo diminua o `count` do produto correspondente. Se você pressionar "–" quando a contagem é 1, o produto deve ser automaticamente removido do carrinho. Certifique-se de que nunca mostre 0. @@ -931,11 +931,11 @@ const initialProducts = [{ count: 1, }, { id: 1, - name: 'Cheese', + name: 'Queijo', count: 5, }, { id: 2, - name: 'Spaghetti', + name: 'Espaguete', count: 2, }]; @@ -988,7 +988,7 @@ button { margin: 5px; } -You can first use `map` to produce a new array, and then `filter` to remove products with a `count` set to `0`: +Você pode primeiro usar `map` para produzir um novo array, e então `filter` para remover produtos com `count` definido como `0`: @@ -1001,11 +1001,11 @@ const initialProducts = [{ count: 1, }, { id: 1, - name: 'Cheese', + name: 'Queijo', count: 5, }, { id: 2, - name: 'Spaghetti', + name: 'Espaguete', count: 2, }]; @@ -1077,9 +1077,9 @@ button { margin: 5px; } -#### Fix the mutations using non-mutative methods {/*fix-the-mutations-using-non-mutative-methods*/} +#### Corrigir as mutações usando métodos não-mutativos {/*fix-the-mutations-using-non-mutative-methods*/} -In this example, all of the event handlers in `App.js` use mutation. As a result, editing and deleting todos doesn't work. Rewrite `handleAddTodo`, `handleChangeTodo`, and `handleDeleteTodo` to use the non-mutative methods: +Neste exemplo, todos os manipuladores de evento em `App.js` usam mutação. Como resultado, editar e deletar todos não funciona. Reescreva `handleAddTodo`, `handleChangeTodo`, e `handleDeleteTodo` para usar os métodos não-mutativos: @@ -1090,9 +1090,9 @@ import TaskList from './TaskList.js'; let nextId = 3; const initialTodos = [ - { id: 0, title: 'Buy milk', done: true }, - { id: 1, title: 'Eat tacos', done: false }, - { id: 2, title: 'Brew tea', done: false }, + { id: 0, title: 'Comprar leite', done: true }, + { id: 1, title: 'Comer tacos', done: false }, + { id: 2, title: 'Fazer chá', done: false }, ]; export default function TaskApp() { @@ -1146,14 +1146,14 @@ export default function AddTodo({ onAddTodo }) { return ( <> setTitle(e.target.value)} /> + }}>Adicionar ) } @@ -1197,7 +1197,7 @@ function Task({ todo, onChange, onDelete }) { }); }} /> ); @@ -1206,7 +1206,7 @@ function Task({ todo, onChange, onDelete }) { <> {todo.title} ); @@ -1225,7 +1225,7 @@ function Task({ todo, onChange, onDelete }) { /> {todoContent} ); @@ -1242,7 +1242,7 @@ ul, li { margin: 0; padding: 0; } -In `handleAddTodo`, you can use the array spread syntax. In `handleChangeTodo`, you can create a new array with `map`. In `handleDeleteTodo`, you can create a new array with `filter`. Now the list works correctly: +Em `handleAddTodo`, você pode usar a sintaxe array spread. Em `handleChangeTodo`, você pode criar um novo array com `map`. Em `handleDeleteTodo`, você pode criar um novo array com `filter`. Agora a lista funciona corretamente: @@ -1253,9 +1253,9 @@ import TaskList from './TaskList.js'; let nextId = 3; const initialTodos = [ - { id: 0, title: 'Buy milk', done: true }, - { id: 1, title: 'Eat tacos', done: false }, - { id: 2, title: 'Brew tea', done: false }, + { id: 0, title: 'Comprar leite', done: true }, + { id: 1, title: 'Comer tacos', done: false }, + { id: 2, title: 'Fazer chá', done: false }, ]; export default function TaskApp() { @@ -1313,14 +1313,14 @@ export default function AddTodo({ onAddTodo }) { return ( <> setTitle(e.target.value)} /> + }}>Adicionar ) } @@ -1364,7 +1364,7 @@ function Task({ todo, onChange, onDelete }) { }); }} /> ); @@ -1373,7 +1373,7 @@ function Task({ todo, onChange, onDelete }) { <> {todo.title} ); @@ -1392,7 +1392,7 @@ function Task({ todo, onChange, onDelete }) { /> {todoContent} ); @@ -1410,9 +1410,9 @@ ul, li { margin: 0; padding: 0; } -#### Fix the mutations using Immer {/*fix-the-mutations-using-immer*/} +#### Corrigir as mutações usando Immer {/*fix-the-mutations-using-immer*/} -This is the same example as in the previous challenge. This time, fix the mutations by using Immer. For your convenience, `useImmer` is already imported, so you need to change the `todos` state variable to use it. +Este é o mesmo exemplo do desafio anterior. Desta vez, corrija as mutações usando Immer. Para sua conveniência, `useImmer` já está importado, então você precisa alterar a variável de estado `todos` para usá-lo. @@ -1424,9 +1424,9 @@ import TaskList from './TaskList.js'; let nextId = 3; const initialTodos = [ - { id: 0, title: 'Buy milk', done: true }, - { id: 1, title: 'Eat tacos', done: false }, - { id: 2, title: 'Brew tea', done: false }, + { id: 0, title: 'Comprar leite', done: true }, + { id: 1, title: 'Comer tacos', done: false }, + { id: 2, title: 'Fazer chá', done: false }, ]; export default function TaskApp() { @@ -1480,14 +1480,14 @@ export default function AddTodo({ onAddTodo }) { return ( <> setTitle(e.target.value)} /> + }}>Adicionar ) } @@ -1531,7 +1531,7 @@ function Task({ todo, onChange, onDelete }) { }); }} /> ); @@ -1540,7 +1540,7 @@ function Task({ todo, onChange, onDelete }) { <> {todo.title} ); @@ -1559,7 +1559,7 @@ function Task({ todo, onChange, onDelete }) { /> {todoContent} ); @@ -1594,7 +1594,7 @@ ul, li { margin: 0; padding: 0; } -With Immer, you can write code in the mutative fashion, as long as you're only mutating parts of the `draft` that Immer gives you. Here, all mutations are performed on the `draft` so the code works: +Com Immer, você pode escrever código de forma mutativa, contanto que você esteja apenas mutando partes do `draft` que Immer lhe dá. Aqui, todas as mutações são realizadas no `draft` então o código funciona: @@ -1606,9 +1606,9 @@ import TaskList from './TaskList.js'; let nextId = 3; const initialTodos = [ - { id: 0, title: 'Buy milk', done: true }, - { id: 1, title: 'Eat tacos', done: false }, - { id: 2, title: 'Brew tea', done: false }, + { id: 0, title: 'Comprar leite', done: true }, + { id: 1, title: 'Comer tacos', done: false }, + { id: 2, title: 'Fazer chá', done: false }, ]; export default function TaskApp() { @@ -1668,14 +1668,14 @@ export default function AddTodo({ onAddTodo }) { return ( <> setTitle(e.target.value)} /> + }}>Adicionar ) } @@ -1719,7 +1719,7 @@ function Task({ todo, onChange, onDelete }) { }); }} /> ); @@ -1728,7 +1728,7 @@ function Task({ todo, onChange, onDelete }) { <> {todo.title} ); @@ -1747,7 +1747,7 @@ function Task({ todo, onChange, onDelete }) { /> {todoContent} ); @@ -1780,9 +1780,9 @@ ul, li { margin: 0; padding: 0; } -You can also mix and match the mutative and non-mutative approaches with Immer. +Você também pode misturar e combinar as abordagens mutativa e não-mutativa com Immer. -For example, in this version `handleAddTodo` is implemented by mutating the Immer `draft`, while `handleChangeTodo` and `handleDeleteTodo` use the non-mutative `map` and `filter` methods: +Por exemplo, nesta versão `handleAddTodo` é implementado mutando o `draft` do Immer, enquanto `handleChangeTodo` e `handleDeleteTodo` usam os métodos não-mutativos `map` e `filter`: @@ -1794,9 +1794,9 @@ import TaskList from './TaskList.js'; let nextId = 3; const initialTodos = [ - { id: 0, title: 'Buy milk', done: true }, - { id: 1, title: 'Eat tacos', done: false }, - { id: 2, title: 'Brew tea', done: false }, + { id: 0, title: 'Comprar leite', done: true }, + { id: 1, title: 'Comer tacos', done: false }, + { id: 2, title: 'Fazer chá', done: false }, ]; export default function TaskApp() { @@ -1853,14 +1853,14 @@ export default function AddTodo({ onAddTodo }) { return ( <> setTitle(e.target.value)} /> + }}>Adicionar ) } @@ -1904,7 +1904,7 @@ function Task({ todo, onChange, onDelete }) { }); }} /> ); @@ -1913,7 +1913,7 @@ function Task({ todo, onChange, onDelete }) { <> {todo.title} ); @@ -1932,7 +1932,7 @@ function Task({ todo, onChange, onDelete }) { /> {todoContent} ); @@ -1965,8 +1965,8 @@ ul, li { margin: 0; padding: 0; } -With Immer, you can pick the style that feels the most natural for each separate case. +Com Immer, você pode escolher o estilo que se sente mais natural para cada caso separado. - + \ No newline at end of file