В Preact, как и в React, жизненный цикл компонентов классов
предоставляет набор методов, позволяющих управлять поведением
компонентов на различных этапах их существования. Среди них ключевое
значение имеют componentDidMount и
componentDidUpdate, которые отвечают за действия после
монтирования компонента в DOM и после его обновления соответственно.
Метод componentDidMount вызывается один раз
после того, как компонент был вставлен в DOM. Это
подходящее место для:
Пример использования:
import { h, Component } from 'preact';
class UserList extends Component {
state = {
users: []
};
componentDidMount() {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(data => this.setState({ users: data }));
}
render() {
return (
<ul>
{this.state.users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
}
Ключевой момент: componentDidMount вызывается только один раз. Любые обновления состояния после этого метода приведут к повторному рендеру, но сам метод не вызовется повторно.
Метод componentDidUpdate вызывается после
каждого обновления компонента, когда изменились
props или state. Он позволяет выполнять
операции, зависящие от новых данных, или синхронизировать состояние с
внешними источниками.
Сигнатура метода:
componentDidUpdate(prevProps, prevState, snapshot)
prevProps — предыдущие свойства компонента.prevState — предыдущее состояние компонента.snapshot — необязательный параметр, возвращаемый
методом getSnapshotBeforeUpdate, используется для
сохранения информации о DOM перед обновлением.Пример использования:
class Timer extends Component {
state = { seconds: 0 };
componentDidUpdate(prevProps, prevState) {
if (prevState.seconds !== this.state.seconds) {
console.log(`Прошло ${this.state.seconds} секунд`);
}
}
tick = () => {
this.setState(state => ({ seconds: state.seconds + 1 }));
};
componentDidMount() {
this.interval = setInterval(this.tick, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <div>Секунды: {this.state.seconds}</div>;
}
}
Важно проверять изменения состояния или свойств,
чтобы избежать бесконечных циклов обновления, поскольку вызов
setState в componentDidUpdate без проверки
приведет к рекурсивному обновлению компонента.
| Метод | Время вызова | Основное назначение |
|---|---|---|
componentDidMount |
После первого рендера компонента | Инициализация данных, работа с DOM, запуск таймеров |
componentDidUpdate |
После каждого обновления | Реакция на изменения props или state,
синхронизация данных |
Механизм работы жизненного цикла:
render().componentDidMount.render().componentDidUpdate.componentDidMount.componentDidUpdate следует аккуратно использовать
setState, всегда проверяя, изменилось ли состояние или
props.fetch,
setTimeout, setInterval) необходимо очищать
ресурсы в componentWillUnmount, чтобы избежать утечек
памяти.getSnapshotBeforeUpdate для
получения информации о DOM перед обновлением, которая затем передается в
componentDidUpdate.class Profile extends Component {
state = { profileData: null };
componentDidMount() {
this.fetchProfile(this.props.userId);
}
componentDidUpdate(prevProps) {
if (prevProps.userId !== this.props.userId) {
this.fetchProfile(this.props.userId);
}
}
fetchProfile(userId) {
fetch(`https://api.example.com/users/${userId}`)
.then(response => response.json())
.then(data => this.setState({ profileData: data }));
}
render() {
if (!this.state.profileData) return <div>Загрузка...</div>;
return (
<div>
<h1>{this.state.profileData.name}</h1>
<p>{this.state.profileData.email}</p>
</div>
);
}
}
В этом примере componentDidUpdate обеспечивает повторную
загрузку данных только при изменении идентификатора пользователя,
предотвращая лишние запросы и ререндеры.
Хотя Preact имеет более лёгкий и быстрый механизм по сравнению с
React, жизненный цикл компонентов и методы
componentDidMount и componentDidUpdate
остаются практически идентичными, что позволяет использовать схожие
подходы к управлению состоянием и асинхронными операциями.