-The problem with this code is in suppressing the dependency linter. If you remove the suppression, you'll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time!
+O problema com este código está na supressão do linter de dependências. Se você remover a supressão, verá que este Effect deveria depender da função `handleMove`. Isso faz sentido: `handleMove` é declarada dentro do corpo do componente, o que a torna um valor reativo. Todo valor reativo deve ser especificado como uma dependência, ou ele pode ficar obsoleto com o tempo!
-The author of the original code has "lied" to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value.
+O autor do código original "mentiu" para o React, dizendo que o Effect não depende (`[]`) de nenhum valor reativo. É por isso que o React não resincronizou o Effect após `canMove` ter mudado (e `handleMove` com ele). Como o React não resincronizou o Effect, o `handleMove` anexado como um listener é a função `handleMove` criada durante a renderização inicial. Durante a renderização inicial, `canMove` era `true`, que é por que `handleMove` da renderização inicial sempre verá esse valor.
-**If you never suppress the linter, you will never see problems with stale values.**
+**Se você nunca suprimir o linter, nunca verá problemas com valores obsoletos.**
-With `useEffectEvent`, there is no need to "lie" to the linter, and the code works as you would expect:
+Com `useEffectEvent`, não há necessidade de "mentir" para o linter, e o código funciona como você esperaria:
@@ -814,7 +814,7 @@ export default function App() {
checked={canMove}
onChange={e => setCanMove(e.target.checked)}
/>
- The dot is allowed to move
+ O ponto pode se mover
-This doesn't mean that `useEffectEvent` is *always* the correct solution. You should only apply it to the lines of code that you don't want to be reactive. In the above sandbox, you didn't want the Effect's code to be reactive with regards to `canMove`. That's why it made sense to extract an Effect Event.
+Isso não significa que `useEffectEvent` seja *sempre* a solução correta. Você só deve aplicá-lo às linhas de código que você não quer que sejam reativas. Na sandbox acima, você não queria que o código do Effect fosse reativo em relação a `canMove`. É por isso que fez sentido extrair um Evento de Effect.
-Read [Removing Effect Dependencies](/learn/removing-effect-dependencies) for other correct alternatives to suppressing the linter.
+Leia [Removendo Dependências de Effect](/learn/removing-effect-dependencies) para outras alternativas corretas para suprimir o linter.
-### Limitations of Effect Events {/*limitations-of-effect-events*/}
+### Limitações dos Eventos de Effect {/*limitations-of-effect-events*/}
-Effect Events are very limited in how you can use them:
+Os Eventos de Effect são muito limitados em como você pode usá-los:
-* **Only call them from inside Effects.**
-* **Never pass them to other components or Hooks.**
+* **Chame-os apenas de dentro de Effects.**
+* **Nunca os passe para outros componentes ou Hooks.**
-For example, don't declare and pass an Effect Event like this:
+Por exemplo, não declare e passe um Evento de Effect como este:
```js {4-6,8}
function Timer() {
@@ -865,7 +865,7 @@ function Timer() {
setCount(count + 1);
});
- useTimer(onTick, 1000); // 🔴 Avoid: Passing Effect Events
+ useTimer(onTick, 1000); // 🔴 Evite: Passar Eventos de Effect
return
{count}
}
@@ -878,11 +878,11 @@ function useTimer(callback, delay) {
return () => {
clearInterval(id);
};
- }, [delay, callback]); // Need to specify "callback" in dependencies
+ }, [delay, callback]); // Precisa especificar "callback" nas dependências
}
```
-Instead, always declare Effect Events directly next to the Effects that use them:
+Em vez disso, sempre declare Eventos de Effect diretamente ao lado dos Effects que os utilizam:
```js {10-12,16,21}
function Timer() {
@@ -900,40 +900,40 @@ function useTimer(callback, delay) {
useEffect(() => {
const id = setInterval(() => {
- onTick(); // ✅ Good: Only called locally inside an Effect
+ onTick(); // ✅ Bom: Chamado apenas localmente dentro de um Effect
}, delay);
return () => {
clearInterval(id);
};
- }, [delay]); // No need to specify "onTick" (an Effect Event) as a dependency
+ }, [delay]); // Não é necessário especificar "onTick" (um Evento de Effect) como dependência
}
```
-Effect Events are non-reactive "pieces" of your Effect code. They should be next to the Effect using them.
+Eventos de Effect são "pedaços" não reativos do seu código de Effect. Eles devem estar ao lado do Effect que os utiliza.
-- Event handlers run in response to specific interactions.
-- Effects run whenever synchronization is needed.
-- Logic inside event handlers is not reactive.
-- Logic inside Effects is reactive.
-- You can move non-reactive logic from Effects into Effect Events.
-- Only call Effect Events from inside Effects.
-- Don't pass Effect Events to other components or Hooks.
+- Manipuladores de eventos são executados em resposta a interações específicas.
+- Effects são executados sempre que a sincronização é necessária.
+- A lógica dentro de manipuladores de eventos não é reativa.
+- A lógica dentro de Effects é reativa.
+- Você pode mover a lógica não reativa de Effects para Eventos de Effect.
+- Chame Eventos de Effect apenas de dentro de Effects.
+- Não passe Eventos de Effect para outros componentes ou Hooks.
-#### Fix a variable that doesn't update {/*fix-a-variable-that-doesnt-update*/}
+#### Corrija uma variável que não atualiza {/*fix-a-variable-that-doesnt-update*/}
-This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable. You can control the `increment` variable with the plus and minus buttons.
+Este componente `Timer` mantém uma variável de estado `count` que aumenta a cada segundo. O valor pelo qual ele está aumentando é armazenado na variável de estado `increment`. Você pode controlar a variável `increment` com os botões de mais e menos.
-However, no matter how many times you click the plus button, the counter is still incremented by one every second. What's wrong with this code? Why is `increment` always equal to `1` inside the Effect's code? Find the mistake and fix it.
+No entanto, não importa quantas vezes você clique no botão de mais, o contador ainda é incrementado em um a cada segundo. O que está errado com este código? Por que `increment` é sempre igual a `1` dentro do código do Effect? Encontre o erro e corrija-o.
-To fix this code, it's enough to follow the rules.
+Para corrigir este código, basta seguir as regras.
@@ -986,9 +986,9 @@ button { margin: 10px; }
-As usual, when you're looking for bugs in Effects, start by searching for linter suppressions.
+Como sempre, ao procurar por bugs em Effects, comece procurando por supressões de linter.
-If you remove the suppression comment, React will tell you that this Effect's code depends on `increment`, but you "lied" to React by claiming that this Effect does not depend on any reactive values (`[]`). Add `increment` to the dependency array:
+Se você remover o comentário de supressão, o React informará que o código deste Effect depende de `increment`, mas você "mentiu" para o React ao afirmar que este Effect não depende de nenhum valor reativo (`[]`). Adicione `increment` ao array de dependências:
@@ -1036,19 +1036,19 @@ button { margin: 10px; }
-Now, when `increment` changes, React will re-synchronize your Effect, which will restart the interval.
+Agora, quando `increment` mudar, o React irá ressincronizar seu Effect, o que reiniciará o intervalo.
-#### Fix a freezing counter {/*fix-a-freezing-counter*/}
+#### Corrija um contador travado {/*fix-a-freezing-counter*/}
-This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable, which you can control it with the plus and minus buttons. For example, try pressing the plus button nine times, and notice that the `count` now increases each second by ten rather than by one.
+Este componente `Timer` mantém uma variável de estado `count` que aumenta a cada segundo. O valor pelo qual ele está aumentando é armazenado na variável de estado `increment`, que você pode controlar com os botões de mais e menos. Por exemplo, tente pressionar o botão de mais nove vezes e observe que o `count` agora aumenta a cada segundo em dez, em vez de um.
-There is a small issue with this user interface. You might notice that if you keep pressing the plus or minus buttons faster than once per second, the timer itself seems to pause. It only resumes after a second passes since the last time you've pressed either button. Find why this is happening, and fix the issue so that the timer ticks on *every* second without interruptions.
+Há um pequeno problema com esta interface de usuário. Você pode notar que, se você continuar pressionando os botões de mais ou menos mais rápido do que uma vez por segundo, o próprio timer parece pausar. Ele só retoma um segundo após a última vez que você pressionou qualquer um dos botões. Descubra por que isso está acontecendo e corrija o problema para que o timer "tick" a cada segundo sem interrupções.
-It seems like the Effect which sets up the timer "reacts" to the `increment` value. Does the line that uses the current `increment` value in order to call `setCount` really need to be reactive?
+Parece que o Effect que configura o timer "reage" ao valor de `increment`. A linha que usa o valor atual de `increment` para chamar `setCount` realmente precisa ser reativa?
@@ -1101,9 +1101,9 @@ button { margin: 10px; }
-The issue is that the code inside the Effect uses the `increment` state variable. Since it's a dependency of your Effect, every change to `increment` causes the Effect to re-synchronize, which causes the interval to clear. If you keep clearing the interval every time before it has a chance to fire, it will appear as if the timer has stalled.
+O problema é que o código dentro do Effect usa a variável de estado `increment`. Como ela é uma dependência do seu Effect, cada mudança em `increment` causa a ressincronização do Effect, o que limpa o intervalo. Se você continuar limpando o intervalo toda vez antes que ele tenha a chance de disparar, parecerá que o timer parou.
-To solve the issue, extract an `onTick` Effect Event from the Effect:
+Para resolver o problema, extraia um Evento de Effect `onTick` do Effect:
@@ -1157,17 +1157,17 @@ button { margin: 10px; }
-Since `onTick` is an Effect Event, the code inside it isn't reactive. The change to `increment` does not trigger any Effects.
+Como `onTick` é um Evento de Effect, o código dentro dele não é reativo. A mudança em `increment` não aciona nenhum Effect.
-#### Fix a non-adjustable delay {/*fix-a-non-adjustable-delay*/}
+#### Corrija um delay não ajustável {/*fix-a-non-adjustable-delay*/}
-In this example, you can customize the interval delay. It's stored in a `delay` state variable which is updated by two buttons. However, even if you press the "plus 100 ms" button until the `delay` is 1000 milliseconds (that is, a second), you'll notice that the timer still increments very fast (every 100 ms). It's as if your changes to the `delay` are ignored. Find and fix the bug.
+Neste exemplo, você pode personalizar o delay do intervalo. Ele é armazenado em uma variável de estado `delay` que é atualizada por dois botões. No entanto, mesmo que você pressione o botão "mais 100 ms" até que o `delay` seja de 1000 milissegundos (ou seja, um segundo), você notará que o timer ainda incrementa muito rapidamente (a cada 100 ms). É como se suas mudanças no `delay` fossem ignoradas. Encontre e corrija o bug.
-Code inside Effect Events is not reactive. Are there cases in which you would _want_ the `setInterval` call to re-run?
+O código dentro de Eventos de Effect não é reativo. Existem casos em que você _gostaria_ que a chamada `setInterval` fosse reexecutada?
@@ -1240,7 +1240,7 @@ button { margin: 10px; }
-The problem with the above example is that it extracted an Effect Event called `onMount` without considering what the code should actually be doing. You should only extract Effect Events for a specific reason: when you want to make a part of your code non-reactive. However, the `setInterval` call *should* be reactive with respect to the `delay` state variable. If the `delay` changes, you want to set up the interval from scratch! To fix this code, pull all the reactive code back inside the Effect:
+O problema com o exemplo acima é que ele extraiu um Evento de Effect chamado `onMount` sem considerar o que o código realmente deveria estar fazendo. Você só deve extrair Eventos de Effect por um motivo específico: quando você quer tornar uma parte do seu código não reativa. No entanto, a chamada `setInterval` *deve* ser reativa em relação à variável de estado `delay`. Se o `delay` mudar, você quer configurar o intervalo do zero! Para corrigir este código, traga todo o código reativo de volta para dentro do Effect:
@@ -1304,21 +1304,21 @@ button { margin: 10px; }
-In general, you should be suspicious of functions like `onMount` that focus on the *timing* rather than the *purpose* of a piece of code. It may feel "more descriptive" at first but it obscures your intent. As a rule of thumb, Effect Events should correspond to something that happens from the *user's* perspective. For example, `onMessage`, `onTick`, `onVisit`, or `onConnected` are good Effect Event names. Code inside them would likely not need to be reactive. On the other hand, `onMount`, `onUpdate`, `onUnmount`, or `onAfterRender` are so generic that it's easy to accidentally put code that *should* be reactive into them. This is why you should name your Effect Events after *what the user thinks has happened,* not when some code happened to run.
+Em geral, você deve desconfiar de funções como `onMount` que se concentram no *timing* em vez do *propósito* de um trecho de código. Pode parecer "mais descritivo" no início, mas obscurece sua intenção. Como regra geral, Eventos de Effect devem corresponder a algo que acontece da perspectiva do *usuário*. Por exemplo, `onMessage`, `onTick`, `onVisit` ou `onConnected` são bons nomes para Eventos de Effect. O código dentro deles provavelmente não precisaria ser reativo. Por outro lado, `onMount`, `onUpdate`, `onUnmount` ou `onAfterRender` são tão genéricos que é fácil colocar acidentalmente código que *deveria* ser reativo neles. É por isso que você deve nomear seus Eventos de Effect com base no *que o usuário pensa que aconteceu*, não quando algum código foi executado por acaso.
-#### Fix a delayed notification {/*fix-a-delayed-notification*/}
+#### Corrigir uma notificação atrasada {/*fix-a-delayed-notification*/}
-When you join a chat room, this component shows a notification. However, it doesn't show the notification immediately. Instead, the notification is artificially delayed by two seconds so that the user has a chance to look around the UI.
+Ao entrar em uma sala de chat, este componente exibe uma notificação. No entanto, a notificação não é exibida imediatamente. Em vez disso, a notificação é artificialmente atrasada em dois segundos para que o usuário tenha a chance de olhar a interface.
-This almost works, but there is a bug. Try changing the dropdown from "general" to "travel" and then to "music" very quickly. If you do it fast enough, you will see two notifications (as expected!) but they will *both* say "Welcome to music".
+Isso quase funciona, mas há um erro. Tente mudar o menu suspenso de "general" para "travel" e depois para "music" muito rapidamente. Se você fizer isso rápido o suficiente, verá duas notificações (como esperado!), mas ambas dirão "Welcome to music".
-Fix it so that when you switch from "general" to "travel" and then to "music" very quickly, you see two notifications, the first one being "Welcome to travel" and the second one being "Welcome to music". (For an additional challenge, assuming you've *already* made the notifications show the correct rooms, change the code so that only the latter notification is displayed.)
+Corrija para que, ao mudar de "general" para "travel" e depois para "music" muito rapidamente, você veja duas notificações, a primeira sendo "Welcome to travel" e a segunda "Welcome to music". (Como um desafio adicional, assumindo que você *já* fez as notificações exibirem as salas corretas, altere o código para que apenas a última notificação seja exibida.)
-Your Effect knows which room it connected to. Is there any information that you might want to pass to your Effect Event?
+Seu Effect sabe a qual sala ele se conectou. Existe alguma informação que você possa querer passar para o seu Evento de Effect?
@@ -1457,11 +1457,11 @@ label { display: block; margin-top: 10px; }
-Inside your Effect Event, `roomId` is the value *at the time Effect Event was called.*
+Dentro do seu Evento de Effect, `roomId` é o valor *no momento em que o Evento de Effect foi chamado*.
-Your Effect Event is called with a two second delay. If you're quickly switching from the travel to the music room, by the time the travel room's notification shows, `roomId` is already `"music"`. This is why both notifications say "Welcome to music".
+Seu Evento de Effect é chamado com um atraso de dois segundos. Se você estiver alternando rapidamente da sala de viagens para a sala de música, quando a notificação da sala de viagens for exibida, `roomId` já será `"music"`. É por isso que ambas as notificações dizem "Welcome to music".
-To fix the issue, instead of reading the *latest* `roomId` inside the Effect Event, make it a parameter of your Effect Event, like `connectedRoomId` below. Then pass `roomId` from your Effect by calling `onConnected(roomId)`:
+Para corrigir o problema, em vez de ler o `roomId` *mais recente* dentro do Evento de Effect, torne-o um parâmetro do seu Evento de Effect, como `connectedRoomId` abaixo. Em seguida, passe `roomId` do seu Effect chamando `onConnected(roomId)`:
@@ -1596,9 +1596,9 @@ label { display: block; margin-top: 10px; }
-The Effect that had `roomId` set to `"travel"` (so it connected to the `"travel"` room) will show the notification for `"travel"`. The Effect that had `roomId` set to `"music"` (so it connected to the `"music"` room) will show the notification for `"music"`. In other words, `connectedRoomId` comes from your Effect (which is reactive), while `theme` always uses the latest value.
+O Effect que teve `roomId` definido como `"travel"` (então ele se conectou à sala `"travel"`) exibirá a notificação para `"travel"`. O Effect que teve `roomId` definido como `"music"` (então ele se conectou à sala `"music"`) exibirá a notificação para `"music"`. Em outras palavras, `connectedRoomId` vem do seu Effect (que é reativo), enquanto `theme` sempre usa o valor mais recente.
-To solve the additional challenge, save the notification timeout ID and clear it in the cleanup function of your Effect:
+Para resolver o desafio adicional, salve o ID do timeout da notificação e limpe-o na função de limpeza do seu Effect:
@@ -1739,8 +1739,8 @@ label { display: block; margin-top: 10px; }
-This ensures that already scheduled (but not yet displayed) notifications get cancelled when you change rooms.
+Isso garante que as notificações já agendadas (mas ainda não exibidas) sejam canceladas quando você muda de sala.
-
+
\ No newline at end of file