Что такое стадия жизненного цикла классового компонента?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Жизненный цикл классового компонента
Жизненный цикл — это последовательность этапов, через которые проходит компонент от создания до удаления из DOM. В классовых компонентах есть специальные методы для реагирования на эти события.
Три стадии жизненного цикла
1. Монтирование (Mounting)
Этап создания компонента и добавления в DOM:
class Component extends React.Component {
constructor(props) {
super(props);
console.log('1. Конструктор');
this.state = { count: 0 };
}
componentDidMount() {
console.log('4. Монтирование завершено');
// Здесь: API запросы, подписки, таймеры
}
render() {
console.log('3. Рендеринг');
return <div>{this.state.count}</div>;
}
// getDerivedStateFromProps (редко используется)
static getDerivedStateFromProps(props, state) {
console.log('2. Получить состояние из пропсов');
return null; // или новое состояние
}
}
// Порядок при монтировании:
// 1. Конструктор
// 2. Получить состояние из пропсов (если есть)
// 3. Рендеринг
// 4. Монтирование завершено
2. Обновление (Updating)
Этап при изменении пропсов или состояния:
class Component extends React.Component {
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('После обновления');
// Сравнить prevProps/prevState с текущими
if (prevProps.id !== this.props.id) {
// Пропсы изменились
this.loadData(this.props.id);
}
}
shouldComponentUpdate(nextProps, nextState) {
console.log('Нужно ли обновлять?');
// Вернуть true (обновить) или false (пропустить)
return nextProps.value !== this.props.value;
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('Перед обновлением DOM');
// Сохранить информацию перед обновлением
return { scrollPosition: window.scrollY };
}
render() {
return <div>{this.props.value}</div>;
}
}
// Порядок при обновлении:
// 1. shouldComponentUpdate (решить обновлять ли)
// 2. getDerivedStateFromProps
// 3. Рендеринг
// 4. getSnapshotBeforeUpdate (перед обновлением DOM)
// 5. componentDidUpdate (после обновления)
3. Размонтирование (Unmounting)
Этап удаления компонента из DOM:
class Component extends React.Component {
componentWillUnmount() {
console.log('Компонент удаляется');
// Очистить: таймеры, подписки, обработчики
clearInterval(this.timer);
this.socket.disconnect();
}
render() {
return <div>Будет удален</div>;
}
}
Практические примеры
API запрос в componentDidMount
class UserProfile extends React.Component {
constructor(props) {
super(props);
this.state = { user: null, loading: true };
}
componentDidMount() {
// Загрузить данные
fetch(`/api/users/${this.props.userId}`)
.then(r => r.json())
.then(user => {
this.setState({ user, loading: false });
})
.catch(err => {
this.setState({ error: err, loading: false });
});
}
render() {
if (this.state.loading) return <div>Загрузка...</div>;
return <div>{this.state.user.name}</div>;
}
}
Отслеживание изменения пропсов
class Component extends React.Component {
componentDidUpdate(prevProps) {
// Если userId изменился
if (prevProps.userId !== this.props.userId) {
this.loadUserData(this.props.userId);
}
}
loadUserData(userId) {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(data => this.setState({ data }));
}
render() {
return <div>{this.state.data?.name}</div>;
}
}
Очистка подписок
class Chat extends React.Component {
componentDidMount() {
// Подписаться на обновления
this.unsubscribe = store.subscribe(() => {
this.forceUpdate();
});
}
componentWillUnmount() {
// Отписаться (важно!)
this.unsubscribe();
}
render() {
return <div>{store.getState().messages}</div>;
}
}
shouldComponentUpdate оптимизация
class Item extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// Обновить только если name или id изменились
return (
nextProps.name !== this.props.name ||
nextProps.id !== this.props.id
);
}
render() {
return <li>{this.props.name}</li>;
}
}
Диаграмма жизненного цикла
МОНТИРОВАНИЕ:
constructor → getDerivedStateFromProps → render → componentDidMount
ОБНОВЛЕНИЕ (пропсы или state):
shouldComponentUpdate → getDerivedStateFromProps → render →
getSnapshotBeforeUpdate → componentDidUpdate
РАЗМОНТИРОВАНИЕ:
componentWillUnmount
ОШИБКА:
componentDidCatch (для обработки ошибок)
Устаревшие методы
В React 16.3+ небезопасны:
// ❌ НЕ используй:
componentWillMount() // Используй constructor или componentDidMount
componentWillReceiveProps() // Используй componentDidUpdate
componentWillUpdate() // Используй componentDidUpdate
Функциональные компоненты вместо классовых
В современном React функциональные компоненты с хуками предпочтительнее:
// Вместо componentDidMount
useEffect(() => {
loadData();
return () => cleanup(); // Вместо componentWillUnmount
}, []);
// Вместо componentDidUpdate
useEffect(() => {
loadData();
}, [dependencies]);
// Вместо shouldComponentUpdate
const Component = React.memo(({ id }) => { ... });
Правила и рекомендации
-
componentDidMount:
- API запросы
- Подписки
- DOM манипуляции
- Таймеры/интервалы
-
componentDidUpdate:
- Сравнивай prevProps/prevState
- Избегай бесконечных циклов
- Обновляй DOM на основе пропсов
-
componentWillUnmount:
- Очищай все ресурсы
- Отписывайся от событий
- Отменяй таймеры
-
shouldComponentUpdate:
- Оптимизируй производительность
- Используй React.memo вместо этого
Вывод
Жизненный цикл классовых компонентов состоит из трёх стадий:
- Монтирование — создание и добавление в DOM
- Обновление — изменение пропсов/состояния
- Размонтирование — удаление из DOM
В современном React рекомендуется использовать функциональные компоненты с хуками вместо классовых компонентов с их жизненным циклом.