ReactJS - Использование useEffect: Полное руководство для начинающих

Здравствуйте, будущие маги React! Сегодня мы отправимся в увлекательное путешествие в мир useEffect в React. Не волнуйтесь, если вы новички в программировании - я буду вашим доброжелательным проводником, и мы будем двигаться шаг за шагом. К концу этого руководства вы будете использовать useEffect, как профессионал!

ReactJS - Using useEffect

Что такое useEffect?

Прежде чем мы углубимся, давайте поймем, что такое useEffect. Представьте, что вы пекете торт. Вы смешиваете ингредиенты, ставите его в духовку, и затем... что? Вы, возможно, хотите поставить таймер, правильно? Это kinda то, что делает useEffect в React. Он позволяет вам выполнять "п побочные эффекты" в ваших компонентах.

П побочные эффекты - это действия, которые происходят alongside вашей компоненты main работы по рендерингу UI. Это могут быть такие вещи, как:

  • Получение данных из API
  • Manual изменение DOM
  • Настройка подписок

Теперь, давайте перейдем к деталям!

Сигнатура useEffect

Хук useEffect имеет определенный способ записи. Давайте разберем его:

useEffect(() => {
// Your effect code here
}, [dependencies]);

Вот что означает каждая часть:

  1. useEffect: Это имя хука, который мы используем.
  2. () => { ... }: Это стрелочная функция, где мы ставим наш код побочного эффекта.
  3. [dependencies]: Это optional массив, где мы перечисляем любые значения, от которых зависит наш эффект.

Давайте посмотрим на простой пример:

import React, { useEffect, useState } from 'react';

function Timer() {
const [seconds, setSeconds] = useState(0);

useEffect(() => {
const interval = setInterval(() => {
setSeconds(prevSeconds => prevSeconds + 1);
}, 1000);

return () => clearInterval(interval);
}, []);

return <div>Seconds: {seconds}</div>;
}

В этом примере мы создаем простой таймер. Хук useEffect настраивает интервал, который увеличивает是我们的 seconds состояние каждую секунду. Пустой массив зависимостей [] означает, что этот эффект будет запускаться только один раз при монтировании компонента.

Функции effect хука

Теперь, когда мы видели базовый пример, давайте рассмотрим некоторые ключевые функции effect хука:

  1. Время: Эффекты запускаются после каждого рендера по умолчанию.
  2. Условное выполнение: Мы можем контролировать, когда запускаются эффекты, используя массив зависимостей.
  3. Очистка: Эффекты могут возвращать функцию очистки, чтобы предотвратить утечки памяти.

Давайте рассмотрим каждую из этих функций подробнее.

Время

По умолчанию useEffect запускается после каждого рендера. Это означает, что если вы обновляете состояние в вашем эффекте, это может вызвать бесконечный цикл! Вот пример того, что НЕЛЬЗЯ делать:

function BadExample() {
const [count, setCount] = useState(0);

useEffect(() => {
setCount(count + 1); // Это вызовет бесконечный цикл!
});

return <div>{count}</div>;
}

Условное выполнение

Чтобы предотвратить ненужные запуски эффектов, мы можем предоставить массив зависимостей:

function ConditionalEffect({ userId }) {
const [user, setUser] = useState(null);

useEffect(() => {
fetchUser(userId).then(data => setUser(data));
}, [userId]);

return <div>{user ? user.name : 'Loading...'}</div>;
}

В этом примере эффект будет запускаться только когда изменится userId.

Очистка

Некоторые эффекты необходимо очистить, чтобы предотвратить утечки памяти. Вот как мы можем это сделать:

function CleanupExample() {
useEffect(() => {
const subscription = subscribeToSomething();

return () => {
subscription.unsubscribe();
};
}, []);

return <div>I'm subscribed!</div>;
}

Функция, возвращаемая из эффекта, будет вызываться при демонтировании компонента.

Получение данных с использованием effect

Одним из распространенных использованием useEffect является получение данных из API. Давайте рассмотрим пример:

function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
setError(error);
setLoading(false);
});
}, []);

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>Data: {JSON.stringify(data)}</div>;
}

Этот компонент получает данные при монтировании, обрабатывает состояния загрузки и ошибки и отображает данные, когда они готовы.

Изменение DOM

useEffect также можно использовать для прямого изменения DOM. Вот пример:

function DOMManipulator() {
useEffect(() => {
const element = document.getElementById('my-element');
element.style.color = 'red';

return () => {
element.style.color = '';
};
}, []);

return <div id="my-element">I'm red!</div>;
}

Этот эффект изменяет цвет элемента на красный при монтировании компонента и сбрасывает его при демонтировании.

Функция очистки

Мы уже касались функций очистки, но давайте углубимся немного больше. Функции очистки критически важны для предотвращения утечек памяти и ненужного поведения. Вот более сложный пример:

function WindowResizer() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);

useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth);
window.addEventListener('resize', handleResize);

return () => {
window.removeEventListener('resize', handleResize);
};
}, []);

return <div>Window width: {windowWidth}px</div>;
}

В этом примере мы добавляем обработчик событий при монтировании компонента и удаляем его при демонтировании. Это предотвращает его hang around после того, как мы больше не нуждаемся в нем.

Итог

Давайте подытожим, что мы узнали о useEffect:

Функция Описание
Сигнатура useEffect(() => { ... }, [dependencies])
Время Запускается после каждого рендера по умолчанию
Условное выполнение Используйте массив зависимостей для управления запуском эффекта
Очистка Возвращайте функцию из эффекта для очистки
Получение данных Можно использовать для получения данных из API
Изменение DOM Можно напрямую изменять DOM
Функция очистки Критически важна для предотвращения утечек памяти

И вот оно! Вы только что сделали свои первые шаги в мир useEffect. Помните, как и любое мощное средство, его нужно практиковаться, чтобы mastered. Так что не бойтесь экспериментировать и делать ошибки - это как мы все учимся. Счастливого кодирования, и пусть ваши эффекты всегда будут чистыми, а ваши компоненты всегда будут реактивными!

Credits: Image by storyset