Какие методы жизненного цикла можно реализовать в классовом компоненте?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы жизненного цикла в классовых React компонентах
Классовые компоненты в React имеют набор методов жизненного цикла (lifecycle methods), которые позволяют выполнять код на различных этапах существования компонента. Хотя в современном React предпочитают функциональные компоненты с хуками, понимание lifecycle методов остаётся важным для работы с legacy кодом и интервью.
Три основные фазы жизненного цикла
1. Mounting (монтирование)
Этап создания компонента и добавления в DOM:
constructor(props)
constructor(props) {
super(props);
this.state = { count: 0 };
// Инициализация, привязка методов
this.handleClick = this.handleClick.bind(this);
}
- Выполняется первым
- Инициализация state и привязка методов
- Единственное место, где можно присвоить this.state напрямую
- Не должен содержать side effects
static getDerivedStateFromProps(props, state)
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.id !== prevState.id) {
return { id: nextProps.id };
}
return null;
}
- Редкий метод, вызывается перед render
- Используется когда state зависит от props
- Возвращает новый state или null
- Без доступа к this
render()
render() {
return <div>{this.state.count}</div>;
}
- Обязательный метод
- Возвращает React элемент
- Должен быть чистой функцией без side effects
- Может вызваться несколько раз
componentDidMount()
componentDidMount() {
fetch('/api/data')
.then(res => res.json())
.then(data => this.setState({ data }));
// Подписка на события
window.addEventListener('resize', this.handleResize);
}
- Вызывается после render и добавления в DOM
- Идеальное место для AJAX запросов
- Установка таймеров, подписок
- Единственное место где это безопасно делать
2. Updating (обновление)
Этап изменения props или state:
static getDerivedStateFromProps(props, state)
- Тот же метод, что в mounting, но может вызваться несколько раз
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.id === this.props.id &&
nextState.count === this.state.count) {
return false; // Пропустить перерендер
}
return true;
}
- Оптимизация производительности
- Возвращает true (перерендер) или false (пропустить)
- По умолчанию возвращает true
- Обычно заменяется React.memo для функциональных компонентов
render()
- Вызывается снова при обновлении
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate(prevProps, prevState) {
// Сохранить позицию скролла перед обновлением
return { scrollY: window.scrollY };
}
- Редкий метод, вызывается перед обновлением DOM
- Результат передаётся в componentDidUpdate
- Используется для сохранения информации о DOM
componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.id !== this.props.id) {
// Выполнить действие при изменении props
this.fetchData();
}
// snapshot содержит результат getSnapshotBeforeUpdate
if (snapshot) {
window.scrollTo(0, snapshot.scrollY);
}
}
- Вызывается после обновления DOM
- Идеальное место для сравнения с предыдущим состоянием
- Безопасно вызывать setState, но нужна условная логика чтобы избежать infinite loop
- Не вызывается при первом монтировании
3. Unmounting (демонтирование)
Этап удаления компонента из DOM:
componentWillUnmount()
componentWillUnmount() {
// Очистка подписок
window.removeEventListener('resize', this.handleResize);
// Отмена таймеров
clearTimeout(this.timerId);
clearInterval(this.intervalId);
// Отмена AJAX запросов
this.abortController?.abort();
}
- Вызывается перед удалением из DOM
- Последний шанс очистить ресурсы
- Отмена подписок, таймеров, запросов
- Очень важен для предотвращения утечек памяти
Deprecated методы (НЕ использовать)
Старые методы, которые удалены в React 18+:
- componentWillMount → заменить на constructor или componentDidMount
- componentWillReceiveProps → заменить на getDerivedStateFromProps
- componentWillUpdate → заменить на getSnapshotBeforeUpdate
Практический пример: загрузка данных
class UserProfile extends React.Component {
constructor(props) {
super(props);
this.state = { user: null, loading: true, error: null };
}
componentDidMount() {
this.fetchUser();
}
componentDidUpdate(prevProps) {
if (prevProps.userId !== this.props.userId) {
this.fetchUser();
}
}
fetchUser = () => {
this.setState({ loading: true });
fetch(`/api/users/${this.props.userId}`)
.then(res => res.json())
.then(user => this.setState({ user, loading: false }))
.catch(error => this.setState({ error, loading: false }));
}
componentWillUnmount() {
// Отмена запросов если необходимо
}
render() {
const { user, loading, error } = this.state;
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{user.name}</div>;
}
}
Современный подход: Hooks
В функциональных компонентах используются хуки вместо lifecycle методов:
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser)
.finally(() => setLoading(false));
}, [userId]); // componentDidMount + componentDidUpdate
useEffect(() => {
// componentWillUnmount
return () => {
// Очистка
};
}, []);
if (loading) return <div>Loading...</div>;
return <div>{user?.name}</div>;
}
Лучше использовать функциональные компоненты с хуками в новом коде, но понимание классовых компонентов остаётся важным для работы с legacy приложениями и интервью.