Skip to content

Commit 752ec02

Browse files
Update separating-events-from-effects.md
reintroduzindo o conteudo que nao foi traduzido pelo fluxo (por conta de token limit do GPT)
1 parent df3eb59 commit 752ec02

File tree

1 file changed

+166
-5
lines changed

1 file changed

+166
-5
lines changed

src/content/learn/separating-events-from-effects.md

Lines changed: 166 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ Há um pequeno problema com essa interface do usuário. Você pode notar que, se
10811081
10821082
<Hint>
10831083
1084-
Parece que o Efeito 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?
1084+
Parece que o Efeito que configura o timer "reage" ao valor de `increment`. A linha que usa o valor atual de `increment` para chamar `setCount` realmente precisa ser reativado?
10851085
10861086
</Hint>
10871087
@@ -1107,6 +1107,75 @@ Parece que o Efeito que configura o timer "reage" ao valor de `increment`. A lin
11071107
import { useState, useEffect } from 'react';
11081108
import { experimental_useEffectEvent as useEffectEvent } from 'react';
11091109

1110+
export default function Timer() {
1111+
const [count, setCount] = useState(0);
1112+
const [increment, setIncrement] = useState(1);
1113+
1114+
useEffect(() => {
1115+
const id = setInterval(() => {
1116+
setCount(c => c + increment);
1117+
}, 1000);
1118+
return () => {
1119+
clearInterval(id);
1120+
};
1121+
}, [increment]);
1122+
1123+
return (
1124+
<>
1125+
<h1>
1126+
Counter: {count}
1127+
<button onClick={() => setCount(0)}>Reset</button>
1128+
</h1>
1129+
<hr />
1130+
<p>
1131+
Every second, increment by:
1132+
<button disabled={increment === 0} onClick={() => {
1133+
setIncrement(i => i - 1);
1134+
}}></button>
1135+
<b>{increment}</b>
1136+
<button onClick={() => {
1137+
setIncrement(i => i + 1);
1138+
}}>+</button>
1139+
</p>
1140+
</>
1141+
);
1142+
}
1143+
```
1144+
1145+
```css
1146+
button { margin: 10px; }
1147+
```
1148+
1149+
</Sandpack>
1150+
1151+
<Solution>
1152+
1153+
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.
1154+
1155+
To solve the issue, extract an `onTick` Effect Event from the Effect:
1156+
1157+
<Sandpack>
1158+
1159+
```json package.json hidden
1160+
{
1161+
"dependencies": {
1162+
"react": "experimental",
1163+
"react-dom": "experimental",
1164+
"react-scripts": "latest"
1165+
},
1166+
"scripts": {
1167+
"start": "react-scripts start",
1168+
"build": "react-scripts build",
1169+
"test": "react-scripts test --env=jsdom",
1170+
"eject": "react-scripts eject"
1171+
}
1172+
}
1173+
```
1174+
1175+
```js
1176+
import { useState, useEffect } from 'react';
1177+
import { experimental_useEffectEvent as useEffectEvent } from 'react';
1178+
11101179
export default function Timer() {
11111180
const [count, setCount] = useState(0);
11121181
const [increment, setIncrement] = useState(1);
@@ -1127,12 +1196,12 @@ export default function Timer() {
11271196
return (
11281197
<>
11291198
<h1>
1130-
Contador: {count}
1131-
<button onClick={() => setCount(0)}>Reiniciar</button>
1199+
Counter: {count}
1200+
<button onClick={() => setCount(0)}>Reset</button>
11321201
</h1>
11331202
<hr />
11341203
<p>
1135-
A cada segundo, incrementar em:
1204+
Every second, increment by:
11361205
<button disabled={increment === 0} onClick={() => {
11371206
setIncrement(i => i - 1);
11381207
}}></button>
@@ -1150,6 +1219,98 @@ export default function Timer() {
11501219
button { margin: 10px; }
11511220
```
11521221
1222+
</Sandpack>
1223+
Since `onTick` is an Effect Event, the code inside it isn't reactive. The change to `increment` does not trigger any Effects.
1224+
1225+
</Solution>
1226+
1227+
#### Fix a non-adjustable delay {/*fix-a-non-adjustable-delay*/}
1228+
1229+
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.
1230+
1231+
<Hint>
1232+
Code inside Effect Events is not reactive. Are there cases in which you would _want_ the `setInterval` call to re-run?
1233+
</Hint>
1234+
1235+
<Sandpack>
1236+
1237+
```json package.json hidden
1238+
{
1239+
"dependencies": {
1240+
"react": "experimental",
1241+
"react-dom": "experimental",
1242+
"react-scripts": "latest"
1243+
},
1244+
"scripts": {
1245+
"start": "react-scripts start",
1246+
"build": "react-scripts build",
1247+
"test": "react-scripts test --env=jsdom",
1248+
"eject": "react-scripts eject"
1249+
}
1250+
}
1251+
```
1252+
1253+
```js
1254+
import { useState, useEffect } from 'react';
1255+
import { experimental_useEffectEvent as useEffectEvent } from 'react';
1256+
1257+
export default function Timer() {
1258+
const [count, setCount] = useState(0);
1259+
const [increment, setIncrement] = useState(1);
1260+
const [delay, setDelay] = useState(100);
1261+
1262+
const onTick = useEffectEvent(() => {
1263+
setCount(c => c + increment);
1264+
});
1265+
1266+
const onMount = useEffectEvent(() => {
1267+
return setInterval(() => {
1268+
onTick();
1269+
}, delay);
1270+
});
1271+
1272+
useEffect(() => {
1273+
const id = onMount();
1274+
return () => {
1275+
clearInterval(id);
1276+
}
1277+
}, []);
1278+
1279+
return (
1280+
<>
1281+
<h1>
1282+
Counter: {count}
1283+
<button onClick={() => setCount(0)}>Reset</button>
1284+
</h1>
1285+
<hr />
1286+
<p>
1287+
Increment by:
1288+
<button disabled={increment === 0} onClick={() => {
1289+
setIncrement(i => i - 1);
1290+
}}></button>
1291+
@@ -1298,22 +1141,11 @@ export default function Timer() {
1292+
setIncrement(i => i + 1);
1293+
}}>+</button>
1294+
</p>
1295+
<p>
1296+
Increment delay:
1297+
<button disabled={delay === 100} onClick={() => {
1298+
setDelay(d => d - 100);
1299+
}}>100 ms</button>
1300+
<b>{delay} ms</b>
1301+
<button onClick={() => {
1302+
setDelay(d => d + 100);
1303+
}}>+100 ms</button>
1304+
</p>
1305+
</>
1306+
);
1307+
}
1308+
```
1309+
1310+
```css
1311+
button { margin: 10px; }
1312+
```
1313+
11531314
</Sandpack>
11541315
11551316
<Solution>
@@ -1673,4 +1834,4 @@ Isso garante que notificações já agendadas (mas ainda não exibidas) sejam ca
16731834
16741835
</Solution>
16751836
1676-
</Challenges>
1837+
</Challenges>

0 commit comments

Comments
 (0)