← Назад к вопросам

Расскажи про жизненный цикл в React

2.2 Middle🔥 231 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Жизненный цикл в React

Реакт компоненты проходят несколько фаз жизненного цикла. В современном React (с функциональными компонентами) это управляется через Hooks, особенно useEffect.

Фазы жизненного цикла

1. Монтирование (Mounting)

Это процесс создания компонента и вставки его в DOM.

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // Фаза монтирования: загружаем данные
    console.log("Компонент смонтирован");
    
    const fetchUser = async () => {
      const response = await fetch(`/api/users/${userId}`);
      const data = await response.json();
      setUser(data);
      setLoading(false);
    };
    
    fetchUser();
  }, []); // Пустой массив зависимостей = выполнить только при монтировании
  
  if (loading) return <div>Загрузка...</div>;
  return <div>{user?.name}</div>;
}

Что происходит:

  • Компонент создаётся
  • Инициализируется состояние (useState)
  • Выполняется эффект с пустым массивом зависимостей
  • Компонент отрисовывается в DOM

2. Обновление (Updating)

Когда состояние или props изменяются, компонент обновляется.

function SearchResults({ query }) {
  const [results, setResults] = useState([]);
  
  useEffect(() => {
    // Фаза обновления: выполняется когда query изменяется
    console.log(`Поиск по запросу: ${query}`);
    
    const searchUsers = async () => {
      const response = await fetch(`/api/search?q=${query}`);
      const data = await response.json();
      setResults(data);
    };
    
    if (query.length > 0) {
      searchUsers();
    } else {
      setResults([]);
    }
  }, [query]); // Выполнить когда query изменяется
  
  return (
    <ul>
      {results.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}

Особенности:

  • Выполняется каждый раз, когда изменяется зависимость
  • Может быть несколько useEffect с разными зависимостями
  • Позволяет разделить логику по смыслу

3. Размонтирование (Unmounting)

Когда компонент удаляется из DOM.

function WebSocketComponent() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    // Монтирование: подключаемся
    const ws = new WebSocket("ws://api.example.com/data");
    
    ws.onmessage = (event) => {
      setData(event.data);
    };
    
    // Размонтирование: очищаем ресурсы
    return () => {
      console.log("Компонент размонтирован, закрываем соединение");
      ws.close();
    };
  }, []); // Эффект один раз при монтировании
  
  return <div>{data}</div>;
}

Важно:

  • Функция, возвращённая из useEffect, это cleanup function
  • Она вызывается перед размонтированием или перед повторным выполнением эффекта
  • Используется для очистки: закрытие соединений, отписка от событий, отмена таймеров

Полный жизненный цикл

function CompleteLifecycle({ id }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  // Эффект 1: Загрузка данных при монтировании
  useEffect(() => {
    console.log("1. Монтирование: загружаем данные");
    setLoading(true);
    
    const loadData = async () => {
      try {
        const response = await fetch(`/api/data/${id}`);
        const result = await response.json();
        setData(result);
        setError(null);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    loadData();
    
    // Cleanup для монтирования
    return () => {
      console.log("Очищаем ресурсы при размонтировании");
    };
  }, []); // Выполнить один раз
  
  // Эффект 2: Реагировать на изменение id
  useEffect(() => {
    console.log("2. Обновление: id изменился на", id);
    // Логика для новых данных
  }, [id]); // Выполнить когда id изменяется
  
  // Эффект 3: Логирование каждого обновления
  useEffect(() => {
    console.log("3. Обновление: данные изменились", data);
  }, [data]); // Выполнить когда data изменяется
  
  if (loading) return <div>Загрузка...</div>;
  if (error) return <div>Ошибка: {error}</div>;
  
  return <div>{data?.name}</div>;
}

Массив зависимостей (Dependency Array)

ЗначениеКогда выполняется
Не указанКаждый раз при обновлении компонента
[]Только один раз при монтировании
[dep1, dep2]Когда dep1 или dep2 изменяются
// Без массива зависимостей — выполняется всегда
useEffect(() => {
  console.log("Выполняется каждый раз");
});

// Пустой массив — выполняется один раз
useEffect(() => {
  console.log("Выполняется при монтировании");
}, []);

// С зависимостями — выполняется при изменении
useEffect(() => {
  console.log("Выполняется когда value изменяется");
}, [value]);

Сравнение с классовыми компонентами

В классовых компонентах есть специальные методы жизненного цикла:

class UserProfile extends React.Component {
  componentDidMount() {
    // Аналог useEffect с []
    console.log("Компонент смонтирован");
  }
  
  componentDidUpdate(prevProps, prevState) {
    // Аналог useEffect без зависимостей
    console.log("Компонент обновлён");
  }
  
  componentWillUnmount() {
    // Аналог cleanup функции
    console.log("Компонент размонтирован");
  }
  
  render() {
    return <div>Содержание</div>;
  }
}

Модерный React предпочитает функциональные компоненты с useEffect.

Практические примеры

Пример 1: Таймер с очисткой

function Timer() {
  const [seconds, setSeconds] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);
    
    // Cleanup: остановить таймер
    return () => clearInterval(interval);
  }, []);
  
  return <div>Прошло {seconds} секунд</div>;
}

Пример 2: Синхронизация с внешним источником

function UserStatus({ userId }) {
  const [status, setStatus] = useState("offline");
  
  useEffect(() => {
    // Подписываемся на обновления
    const unsubscribe = subscribeToUserStatus(userId, (newStatus) => {
      setStatus(newStatus);
    });
    
    // Cleanup: отписываемся
    return () => unsubscribe();
  }, [userId]);
  
  return <div>Статус: {status}</div>;
}

Ключевые моменты

  • Монтирование — когда компонент появляется в DOM
  • Обновление — когда состояние или props изменяются
  • Размонтирование — когда компонент удаляется из DOM
  • useEffect — основной хук для управления жизненным циклом
  • Cleanup функция — важна для избежания утечек памяти
  • Массив зависимостей — контролирует когда эффект выполняется

Понимание жизненного цикла критично для написания производительного и надёжного React кода.

Расскажи про жизненный цикл в React | PrepBro