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

Какие методы жизненного цикла есть в React?

1.3 Junior🔥 121 комментариев
#React

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

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

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

Методы жизненного цикла в React

Жизненный цикл компонента — это набор методов, которые вызываются в определённые моменты существования компонента: при создании, обновлении и удалении. В современном React используются функциональные компоненты с хуками, которые заменили устаревшие методы класс-компонентов.

Старый подход: методы классовых компонентов

В классовых компонентах существовали три фазы:

Фаза монтирования (Mounting)

Это происходит когда компонент добавляется в DOM:

  • constructor() — инициализация состояния и привязка методов
  • render() — возвращает JSX
  • componentDidMount() — вызывается после монтирования, здесь загружают данные с API
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  componentDidMount() {
    console.log("Компонент смонтирован");
    // Загрузка данных
    fetch("/api/data").then(res => res.json());
  }

  render() {
    return <div>{this.state.count}</div>;
  }
}

Фаза обновления (Updating)

Возникает когда меняются props или state:

  • shouldComponentUpdate() — можно оптимизировать, вернув false чтобы пропустить render
  • render() — перерисовка
  • componentDidUpdate(prevProps, prevState) — вызывается после обновления, используется для сравнения старых и новых значений
componentDidUpdate(prevProps, prevState) {
  if (prevProps.id !== this.props.id) {
    // ID изменился, загрузим новые данные
    this.loadData();
  }
}

Фаза размонтирования (Unmounting)

  • componentWillUnmount() — вызывается перед удалением из DOM, здесь очищают ресурсы (отписка от событий, отмена запросов)
componentWillUnmount() {
  // Очистка: отписка от слушателей, отмена таймаутов
  window.removeEventListener("resize", this.handleResize);
  clearTimeout(this.timer);
}

Современный подход: хуки в функциональных компонентах

В React 16.8+ вместо методов жизненного цикла используются хуки, которые проще и интуитивнее.

useEffect — это основной хук, заменяющий все три фазы:

function MyComponent({ id }) {
  const [data, setData] = useState(null);

  // Эквивалент componentDidMount + componentDidUpdate
  useEffect(() => {
    console.log("Загрузка данных для id:", id);
    fetch(`/api/data/${id}`)
      .then(res => res.json())
      .then(setData);

    // Очистка (эквивалент componentWillUnmount)
    return () => {
      console.log("Очистка ресурсов");
    };
  }, [id]); // Зависимость: эффект запустится только если id изменился

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

Массив зависимостей (dependency array)

Это ключевой момент в useEffect:

  • [] (пустой) — эффект выполняется один раз после монтирования (аналог componentDidMount)
  • [id] — эффект выполняется когда id изменился
  • без массива — эффект выполняется после каждого рендера (опасно!)
// Один раз при монтировании
useEffect(() => {
  console.log("Компонент создан");
}, []);

// При изменении userId
useEffect(() => {
  loadUser(userId);
}, [userId]);

// После каждого рендера (плохая идея в большинстве случаев)
useEffect(() => {
  console.log("После каждого рендера");
});

Другие полезные хуки

useLayoutEffect — как useEffect, но выполняется синхронно после DOM-изменений, до browser paint. Используется редко, для измерения размеров элементов.

useLayoutEffect(() => {
  const width = divRef.current.offsetWidth;
  console.log("Ширина:", width);
}, []);

useCallback и useMemo — для оптимизации производительности, чтобы избежать ненужных пересчётов.

Практический пример: загрузка списка постов

function PostList({ userId }) {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    setError(null);

    fetch(`/api/users/${userId}/posts`)
      .then(res => {
        if (!res.ok) throw new Error("Ошибка загрузки");
        return res.json();
      })
      .then(data => {
        setPosts(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, [userId]);

  if (loading) return <div>Загрузка...</div>;
  if (error) return <div>Ошибка: {error}</div>;

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Ключевые различия старого и нового подходов

Классовые компоненты разделяют логику по жизненному циклу (componentDidMount, componentDidUpdate в разных местах), а хуки позволяют группировать связанную логику вместе в одном useEffect. Это делает код понятнее и проще переиспользовать через кастомные хуки.

Вывод: в современной разработке используют функциональные компоненты с useEffect. Знание старых методов нужно для поддержки legacy кода, но новое пишут только на хуках.