Skip to content

Commit e403f76

Browse files
committed
fix: добавлена инфа согласно код-ревью
1 parent 6305136 commit e403f76

1 file changed

Lines changed: 92 additions & 4 deletions

File tree

lessons/lesson31/lesson.md

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ description: "Hooks в React: useState, useEffect, useCallback, useMemo"
2525

2626
<!-- v -->
2727

28-
Жизненные этапы и циклы React-компонента
29-
3028
<img src="./images/react-lifecycle.jpg" title="react lifecicles" />
3129

3230
<!-- v -->
@@ -55,6 +53,46 @@ const [state, setState] = useState(initialState);
5553

5654
<!-- v -->
5755

56+
<small>
57+
58+
Разница между setAge(age => age + 1) и setAge(age + 1)
59+
60+
1. React НЕ обновляет состояние сразу
61+
2. Обновления ставятся в очередь
62+
3. Батчинг (batch) - несколько setState (обновлений состояния) за один рендер
63+
64+
</small>
65+
66+
```jsx
67+
// ❌ ПЛОХО - не работает
68+
function Counter() {
69+
const [age, setAge] = useState(0);
70+
71+
const increment = () => {
72+
setAge(age + 1); // setCount(0 + 1) → setCount(1)
73+
setAge(age + 1); // setCount(0 + 1) → setCount(1)
74+
// Результат: age увеличится только на 1, а не на 2!
75+
};
76+
77+
return <button onClick={increment}>+2</button>;
78+
}
79+
80+
// ✅ ХОРОШО - работает правильно
81+
function Counter() {
82+
const [age, setAge] = useState(0);
83+
84+
const increment = () => {
85+
setAge((prev) => prev + 1); // prev = 0 → 1
86+
setAge((prev) => prev + 1); // prev = 1 → 2
87+
// Результат: age = 2
88+
};
89+
90+
return <button onClick={increment}>+2</button>;
91+
}
92+
```
93+
94+
<!-- v -->
95+
5896
```javascript
5997
import { useState } from "react";
6098

@@ -165,8 +203,8 @@ export default function Form() {
165203

166204
<!-- v -->
167205

168-
[useEffect](https://ru.react.dev/reference/react/useEffect) позволяет управлять различными сопутствующими действиями в функциональном компоненте или то, что называется **_"side effects" (побочные эффекты)_**,
169-
например, извлечение данных, ручное изменение структуры DOM, использование таймеров, логгирование и т.д.
206+
- [useEffect](https://ru.react.dev/reference/react/useEffect) позволяет управлять различными сопутствующими действиями в функциональном компоненте или то, что называется **_"side effects" (побочные эффекты)_**,
207+
например, извлечение данных, ручное изменение структуры DOM, использование таймеров, логгирование и т.д.
170208

171209
<!-- v -->
172210

@@ -275,6 +313,56 @@ export default function UseEffectPage({ userId = 2 }) {
275313
276314
<!-- v -->
277315
316+
Как правильно использовать асинхронные функции в React useEffect
317+
318+
```jsx
319+
// !!! Не делайте так!
320+
useEffect(async () => {
321+
const data = await fetchData();
322+
}, []);
323+
```
324+
325+
- Проблема: useEffect ожидает функцию, которая возвращает либо undefined, либо функцию очистки, а async функция возвращает Promise.
326+
327+
<!-- v -->
328+
329+
Правильный способ
330+
331+
```jsx
332+
useEffect(() => {
333+
const fetchData = async () => {
334+
const data = await fetch("https://api.com");
335+
const json = await data.json();
336+
setData(json); // Обновляем состояние ВНУТРИ асинхронной функции
337+
};
338+
339+
fetchData().catch(console.error);
340+
}, []);
341+
```
342+
343+
```jsx
344+
// функция вынесена наружу
345+
const fetchData = useCallback(async () => {
346+
const data = await fetch("https://api.com");
347+
setData(data);
348+
}, []);
349+
350+
useEffect(() => {
351+
fetchData().catch(console.error);
352+
}, [fetchData]);
353+
```
354+
355+
<!-- v -->
356+
357+
Ключевые моменты:
358+
359+
1. Не делайте useEffect async - это нарушает его контракт
360+
2. Создавайте асинхронные функции внутри useEffect
361+
3. Обрабатывайте ошибки с помощью .catch()
362+
4. Используйте useCallback если выносите функцию наружу
363+
364+
<!-- v -->
365+
278366
## Вопросы?
279367
280368
<!-- v -->

0 commit comments

Comments
 (0)