+ >
+ );
+}
+```
+
+
+
+## Вопросы?
+
+
+
+## useEffect
+
+
+
+- [useEffect](https://ru.react.dev/reference/react/useEffect) позволяет управлять различными сопутствующими действиями в функциональном компоненте или то, что называется **_"side effects" (побочные эффекты)_**,
+ например, извлечение данных, ручное изменение структуры DOM, использование таймеров, логгирование и т.д.
+
+
+
+```jsx
+useEffect(setup, dependencies?)
+```
+
+- **setup**: Функция с логикой эффекта.
+
+- опциональные **dependencies**: массив зависимостей, который говорит хуку, когда нужно сработать.
+
+
+
+Есть 3 варианта передачи зависимостей в данных хук:
+
+1. Не передать ничего
+2. Передать пустой массив - []
+3. Передать массив с переменными для отслеживания - [value]
+
+
+
+1. Не передать ничего
+
+```jsx
+import { useEffect, useState } from "react";
+
+export default function UseEffectPage() {
+ const [value, setValue] = useState({});
+
+ useEffect(() => {
+ // Эффект срабатывает при монтировании компонента и при каждом рендере.
+ console.log("Срабатываю на каждый рендер");
+ });
+
+ return (
+
+ );
+}
+```
+
+
+
+Как правильно использовать асинхронные функции в React useEffect
+
+```jsx
+// !!! Не делайте так!
+useEffect(async () => {
+ const data = await fetchData();
+}, []);
+```
+
+- Проблема: useEffect ожидает функцию, которая возвращает либо undefined, либо функцию очистки, а async функция возвращает Promise.
+
+
+
+Правильный способ
+
+```jsx
+useEffect(() => {
+ const fetchData = async () => {
+ const data = await fetch("https://api.com");
+ const json = await data.json();
+ setData(json); // Обновляем состояние ВНУТРИ асинхронной функции
+ };
+
+ fetchData().catch(console.error);
+}, []);
+```
+
+```jsx
+// функция вынесена наружу
+const fetchData = useCallback(async () => {
+ const data = await fetch("https://api.com");
+ setData(data);
+}, []);
+
+useEffect(() => {
+ fetchData().catch(console.error);
+}, [fetchData]);
+```
+
+
+
+Ключевые моменты:
+
+1. Не делайте useEffect async - это нарушает его контракт
+2. Создавайте асинхронные функции внутри useEffect
+3. Обрабатывайте ошибки с помощью .catch()
+4. Используйте useCallback если выносите функцию наружу
+
+
+
+## Вопросы?
+
+
+
+У useEffect есть важная возможность -
+возвращать функцию очистки
+
+```jsx
+// Монтирование, размонтирование и обновление
+useEffect(() => {
+ // Код выполняется ПРИ монтировании компонента (componentDidMount)
+ // и ПРИ обновлении зависимостей из массива (componentDidUpdate)
+
+ return () => {
+ // Функция очистки выполняется:
+ // - ПЕРЕД повторным выполнением эффекта (при изменении зависимостей)
+ // - ПРИ РАЗмонтировании компонента (componentWillUnmount)
+ };
+}, [dep1, dep2, dep3]); // Массив зависимостей
+```
+
+
+
+Пример очистки функции с интервалом
+
+```jsx
+export default function Timer() {
+ const [time, setTime] = useState(new Date().toLocaleTimeString());
+
+ useEffect(() => {
+ console.log("✅ Таймер запущен");
+
+ // Запускаем интервал при монтировании
+ const intervalId = setInterval(() => {
+ const currentTime = new Date().toLocaleTimeString();
+ setTime(currentTime);
+ console.log("🕒 Время обновлено:", currentTime);
+ }, 1000);
+
+ // Функция очистки
+ return () => {
+ console.log("Таймер остановлен");
+ clearInterval(intervalId);
+ };
+ }, []); // Пустой массив - эффект только при монтировании/размонтировании
+
+ return (
+
+
Текущее время: {time}
+
+ );
+}
+```
+
+
+
+## Вопросы?
+
+
+
+## useMemo
+
+
+
+[useMemo](https://ru.react.dev/reference/react/useMemo) - мемоизация значений, кеширует результаты вычислений между ререндерами.
+Служит для **_оптимизации_**!
+
+- **_Проблема:_** Сложные вычисления внутри компонента выполняются при каждом рендере, даже если их входные данные не изменились.
+
+- Вычисление повторяется только при изменении зависимостей.
+
+
+
+```jsx
+const memoizedValue = useMemo(calculateValue, dependencyArray);
+```
+
+- **_calculateValue_**: Функция, вычисляющая значение, которое хотите кэшировать.
+ Она должна быть чистой, не принимать аргументов и возвращать значение любого типа.
+
+- **_dependencies_**: Список всех реактивных значений, на которые ссылается код calculateValue.
+ Реактивные значения - это данные, при изменении которых React должен "отреагировать" и перерендерить компонент.
+
+
+
+```jsx
+import { useMemo } from "react";
+
+export default function TodoList({ todos, filter }) {
+ // БЕЗ useMemo: фильтрация происходит при каждом рендере
+
+ // С useMemo: фильтрация происходит только при изменении todos или filter
+ const visibleTodos = useMemo(() => {
+ console.log("🟢 ФИЛЬТРАЦИЯ (с useMemo)"); // Логируется только при изменении зависимостей
+ return todos.filter(
+ (todo) =>
+ filter === "all" ||
+ (filter === "completed" && todo.completed) ||
+ (filter === "active" && !todo.completed)
+ );
+ }, [todos, filter]); // Зависимости: todos и filter
+
+ return (
+
+ {visibleTodos.map((todo) => (
+
{todo.text}
+ ))}
+
+ );
+}
+```
+
+
+
+## Вопросы?
+
+
+
+## useCallback
+
+
+
+[useCallback](https://ru.react.dev/reference/react/useCallback) - мемоизация функций (кеширование функции между повторными рендерингами).
+Служит для **_оптимизации_**!
+
+- **_Проблема:_** При каждом рендере создаются новые функции. Если передать такую функцию в дочерний компонент, это вызовет его ненужный перерендер.
+
+- **_Решение:_** useCallback мемоизирует (запоминает) функцию между рендерами, чтобы она не создавалась заново при каждом рендеринге.
+
+- Функция пересоздается только при изменении зависимостей.
+
+
+
+```jsx
+const cachedFn = useCallback(fn, dependencies);
+```
+
+- **_fn_**
+ значение функции, которое вы хотите кэшировать. Она может принимать любые аргументы и возвращать любые значения.
+ React вернет (**_не вызовет!_**) вашу функцию обратно во время первоначального рендера.
+ React не будет вызывать вашу функцию. Функция возвращается вам, чтобы вы могли решить, когда и стоит ли ее вызывать.
+
+- **_dependencies_**
+ Список всех реактивных значений, на которые ссылается код fn.
+ Реактивные значения включают пропсы, состояние, а также все переменные и функции, объявленные непосредственно в теле вашего компонента.
+
+
+
+```jsx
+import { useCallback, useState } from "react";
+
+function useCallbackPage1() {
+ const [counter, setCounter] = useState(0);
+
+ const incrementCounter = useCallback(() => {
+ setCounter(counter + 1);
+ }, [counter]);
+
+ return (
+ <>
+
useCallback
+
{counter}
+
+ >
+ );
+}
+```
+
+
+
+## Вопросы?
+
+
+
+## React.memo
+
+
+
+- [React.memo](https://ru.react.dev/reference/react/memo) - функция, которую используем для оборачивания компонента, в результате чего получаем новый компонент
+ ==> **_memo_** - компонент высшего порядка HOC.
+ Служит для **_оптимизации_**!
+
+- **_HOC (Higher-Order Component)_** - функция, которая на входе принимает один компонент, а на выходе возвращает новый с более расширенным функционалом
+
+
+
+**_React.memo_** позволяет пропустить повторный рендер, когда пропсы не изменились.
+
+```jsx
+const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
+```
+
+```jsx
+import { memo } from "react";
+
+const SomeComponent = memo(function SomeComponent(props) {
+ // ...
+});
+```
+
+
+
+```jsx
+// Дочерний компонент, который мы хотим оптимизировать
+export const CounterButton = memo(({ onClick, label }) => {
+ console.log("Кнопка перерендерилась:", label);
+
+ return ;
+});
+```
+
+
+
+## Вопросы?
+
+
+
+## Опрос
+
+
+
+## Дополнительные рекомендации
+
+
+
+
+
+| Инструмент | Что делает | Когда использовать | На что влияет |
+| --------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| **useState** | Управляет состоянием компонента | Компоненту нужно хранить изменяемые данные. Пользовательский ввод, флаги, счётчики | Вызывает ререндер при обновлении и изменяет внутреннее состояние компонента |
+| **useEffect** | Выполняет побочные эффекты | - Запросы к API - Подписки на события - Таймеры, интервалы - Синхронизация с внешними системами | - Выполняет код после рендера - Может влиять на производительность при неправильных зависимостях |
+| **useCallback** | Мемоизирует функцию | Если функция передается в пропсы или в зависимость useEffect/useMemo | Предотвращает создание новой функции при каждом рендере |
+| **useMemo** | Мемоизирует значение | Если начение считается долго и зависит от пропсов/стейта | Предотвращает повторные вычисления |
+| **React.memo** | Мемоизирует компонент | Если компонент часто ререндерится с одинаковыми пропсами | Предотвращает лишние ререндеры компонента |
+
+
+
+
+
+
+
+| Инструмент | Когда НЕ нужно использовать |
+| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **React.memo** | • Если компонент рендерится быстро, так как его оптимизация не даст заметного выигрыша в производительности. • Если пропсы всегда изменяются (например, передаются динамические данные). • Если добавление React.memo усложняет код и снижает его читаемость. |
+| **useMemo** | • Если вычисление несложное и выполняется быстро. • Если зависимости часто меняются, из-за чего мемоизация теряет смысл. • Если нужно кэшировать примитивные значения - React уже оптимизирует эти случаи. |
+| **useCallback** | • Если функция используется только внутри компонента и не передаётся в другие компоненты. • Если функция простая и выполняется быстро. • Если зависимости функции обновляются при каждом рендере, что делает её мемоизацию бесполезной. |
+
+
+
+
+
+###### 📍 Правила применения:
+
+- **Сначала работающий код** → потом оптимизация
+- **Измеряйте производительность** перед оптимизацией
+
+
+
+Дополнительные материалы:
+
+**_React Official Docs (обязательно к изучению)_**
+
+- [useState](https://ru.react.dev/reference/react/useState)
+- [useEffect](https://ru.react.dev/reference/react/useEffect)
+- [useCallback](https://ru.react.dev/reference/react/useCallback)
+- [React.memo](https://ru.react.dev/reference/react/memo)
+- [useMemo](https://ru.react.dev/reference/react/useMemo)
+
+- [React Hooks Full Course](https://www.freecodecamp.org/news/react-hooks-fundamentals/) - бесплатный курс на английском
+
+
+
+## Благодарю за внимание!