Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы жизненного цикла в 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 кода, но новое пишут только на хуках.