ReactJS - Component Life Cycle

Привет, будущие разработчики React! Сегодня мы отправляемся в увлекательное путешествие через жизненный цикл компонентов React. Не волнуйтесь, если вы новички в программировании - я буду вашим дружелюбным проводником, объясняя все шаг за шагом. К концу этого руководства у вас будет прочное понимание того, как рождаются, растут и, наконец, прощаются компоненты React. Погружаемся!

ReactJS - Component Life Cycle

Что такое жизненный цикл?

Прежде чем мы перейдем к коду, давайте поговорим о том, что мы понимаем под "жизненным циклом". Так же, как и мы, люди, проходим через разные stages жизни (рождение, рост и, эhm...), компоненты React также имеют свои собственные жизненные этапы. Эти этапы называются жизненным циклом компонента.

Представьте себе компонент React как виртуального питомца. Когда вы его впервые создаете, он рождается. Затем он растет и изменяется по мере вашего взаимодействия с ним. Наконец, когда он вам больше не нужен, он уходит. Понимание этого жизненного цикла критически важно для создания динамичных и эффективных приложений React.

Три основные фазы жизни компонента

Компоненты React проходят три основные фазы:

  1. Монтаж (Рождение)
  2. Обновление (Рост)
  3. Демонтаж (Прощание)

Давайте рассмотрим каждую из этих фаз и методы, связанные с ними.

1. Фаза монтажа

Это когда наш компонент рождается и добавляется в DOM (Document Object Model - представьте его как семейное древо вашего веб-страницы).

Основные методы этой фазы:

Метод Описание
constructor() Конструктор компонента, вызывается перед его монтажом
render() Метод, который действительно рендерит компонент
componentDidMount() Вызывается после того, как компонент смонтирован в DOM

Давайте посмотрим на простой пример:

import React, { Component } from 'react';

class BabyComponent extends Component {
constructor(props) {
super(props);
this.state = { message: "Я только что родился!" };
console.log("Конструктор: Привет, я создаюсь!");
}

componentDidMount() {
console.log("componentDidMount: Я теперь в DOM!");
}

render() {
console.log("Render: Меня рендерят!");
return <h1>{this.state.message}</h1>;
}
}

export default BabyComponent;

В этом примере наш BabyComponent проходит через свою фазу рождения. Сначала вызывается constructor, устанавливая начальное состояние. Затем вызывается render, чтобы создать реальные DOM-элементы. Наконец, componentDidMount вызывается, сигнализируя о том, что наш компонент полностью родился и добавлен в DOM.

2. Фаза обновления

Эта фаза occurs, когда состояние компонента изменяется или он получает новые пропсы.

Основные методы этой фазы:

Метод Описание
shouldComponentUpdate() Решает, должен ли компонент перерендериться
render() Перерендерит компонент с обновленными данными
componentDidUpdate() Вызывается после обновления компонента

Давайте расширяем наш предыдущий пример:

import React, { Component } from 'react';

class GrowingComponent extends Component {
constructor(props) {
super(props);
this.state = { age: 0 };
}

componentDidMount() {
this.ageInterval = setInterval(() => {
this.setState(prevState => ({ age: prevState.age + 1 }));
}, 1000);
}

shouldComponentUpdate(nextProps, nextState) {
return nextState.age % 5 === 0; // Обновлять только через каждые 5 лет
}

componentDidUpdate() {
console.log(`Я только что стал ${this.state.age} лет!`);
}

render() {
return <h1>Мне ${this.state.age} лет</h1>;
}

componentWillUnmount() {
clearInterval(this.ageInterval);
}
}

export default GrowingComponent;

В этом примере наш GrowingComponent "становится старше" каждую секунду. Метод shouldComponentUpdate обеспечивает то, что мы庆祝уем дни рождения только через каждые 5 лет (чтобы сэкономить на тортах, вы понимаете). Когда компонент действительно обновляется, componentDidUpdate логирует поздравление с днем рождения.

3. Фаза демонтажа

Это прощальная фаза, когда компонент удаляется из DOM.

Основной метод этой фазы:

Метод Описание
componentWillUnmount() Вызывается непосредственно перед демонтажем и разрушением компонента

В нашем примере GrowingComponent мы использовали componentWillUnmount, чтобы清除 установленный интервал, предотвращая утечку памяти.

Пример жизненного цикла API

Теперь давайте объединим все в более сложном примере. Мы создадим простое приложение "Трекер настроения", которое демонстрирует все методы жизненного цикла.

import React, { Component } from 'react';

class MoodTracker extends Component {
constructor(props) {
super(props);
this.state = { mood: 'нейтральное', intensity: 5 };
console.log('Конструктор: Трекер настроения создается');
}

componentDidMount() {
console.log('ComponentDidMount: Трекер настроения теперь в DOM');
this.moodInterval = setInterval(() => {
const moods = ['счастливый', ' печальный', 'восторженный', 'нервный', 'нейтральный'];
const newMood = moods[Math.floor(Math.random() * moods.length)];
this.setState({ mood: newMood });
}, 5000);
}

shouldComponentUpdate(nextProps, nextState) {
return this.state.mood !== nextState.mood;
}

componentDidUpdate() {
console.log(`Настроение обновлено: ${this.state.mood}`);
}

componentWillUnmount() {
console.log('ComponentWillUnmount: Пока Трекер настроения!');
clearInterval(this.moodInterval);
}

handleIntensityChange = (e) => {
this.setState({ intensity: e.target.value });
}

render() {
console.log('Render: Трекер настроения рендерится');
return (
<div>
<h1>Текущее настроение: {this.state.mood}</h1>
<input
type="range"
min="1"
max="10"
value={this.state.intensity}
onChange={this.handleIntensityChange}
/>
<p>Интенсивность: {this.state.intensity}</p>
</div>
);
}
}

export default MoodTracker;

Этот компонент MoodTracker демонстрирует все методы жизненного цикла, о которых мы говорили. Онrandomly изменяет настроение каждые 5 секунд и позволяет пользователю изменять интенсивность настроения.

Жизненный цикл API в приложении "Менеджер расходов"

Теперь давайте рассмотрим, как мы можем использовать эти методы жизненного цикла в практическом приложении, таком как "Менеджер расходов".

import React, { Component } from 'react';

class ExpenseManager extends Component {
constructor(props) {
super(props);
this.state = { expenses: [], total: 0 };
}

componentDidMount() {
// Симулируем получение расходов из API
setTimeout(() => {
const fetchedExpenses = [
{ id: 1, description: 'Продукты', amount: 50 },
{ id: 2, description: 'Бензин', amount: 30 },
{ id: 3, description: 'Билеты в кино', amount: 20 },
];
this.setState({ expenses: fetchedExpenses }, this.calculateTotal);
}, 1000);
}

shouldComponentUpdate(nextProps, nextState) {
// Обновлять только если changed total
return this.state.total !== nextState.total;
}

componentDidUpdate() {
console.log(`Общий расход обновлен: $${this.state.total}`);
}

calculateTotal = () => {
const total = this.state.expenses.reduce((sum, expense) => sum + expense.amount, 0);
this.setState({ total });
}

render() {
return (
<div>
<h1>Менеджер расходов</h1>
<ul>
{this.state.expenses.map(expense => (
<li key={expense.id}>{expense.description}: ${expense.amount}</li>
))}
</ul>
<h2>Итого: ${this.state.total}</h2>
</div>
);
}
}

export default ExpenseManager;

В этом компоненте ExpenseManager:

  1. Мы используем componentDidMount, чтобы симулировать получение данных о расходах из API, когда компонент впервые загружается.
  2. shouldComponentUpdate обеспечивает то, что мы перерендерим компонент только если изменится общая сумма.
  3. componentDidUpdate логирует новую общую сумму, whenever она изменяется.

Используя эти методы жизненного цикла, мы создаем более эффективное иresponsive приложение для отслеживания расходов.

Понимание жизненного цикла компонента критически важно для создания эффективных приложений React. Оно позволяет вам контролировать, когда occur certain действия, оптимизировать производительность и эффективно управлять ресурсами. Продолжайте практиковаться с этими conceptами, и вскоре вы сможете легко создавать сложные и динамичные приложения React!

Credits: Image by storyset