Локальное состояние компонентов

Локальное состояние компонентов в Inferno играет ключевую роль в управлении динамическими данными внутри приложения. Оно позволяет компоненту хранить информацию, изменять её и автоматически обновлять интерфейс при изменении состояния, без необходимости взаимодействия с глобальными хранилищами данных.

Создание состояния в классовых компонентах

В классовых компонентах состояние определяется в конструкторе через объект state.

import { Component } from 'inferno';

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

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <p>Счётчик: {this.state.count}</p>
        <button onCl ick={this.increment}>Увеличить</button>
      </div>
    );
  }
}

Ключевые моменты:

  • this.state хранит данные компонента.
  • Метод setState запускает повторный рендеринг компонента, обновляя только изменившиеся части DOM.
  • setState может принимать объект или функцию для вычисления нового состояния на основе предыдущего:
this.setState(prevState => ({ count: prevState.count + 1 }));

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

Локальное состояние в функциональных компонентах

Inferno поддерживает хуки, аналогичные React, через пакет inferno-hooks. Основной хук для локального состояния — useState.

import { useState } from 'inferno-hooks';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);

  return (
    <div>
      <p>Счётчик: {count}</p>
      <button onCl ick={increment}>Увеличить</button>
    </div>
  );
}

Особенности:

  • useState возвращает массив из двух элементов: текущее значение состояния и функцию для его изменения.
  • Изменение состояния через функцию setCount вызывает повторный рендер компонента.
  • Начальное значение состояния передаётся при вызове useState.

Асинхронные обновления состояния

Inferno обеспечивает батчинг обновлений состояния, что позволяет оптимизировать повторные вызовы setState.

incrementMultiple = () => {
  this.setState({ count: this.state.count + 1 });
  this.setState({ count: this.state.count + 1 });
};

Без использования функции для вычисления нового состояния результат может быть неожиданным, так как оба вызова будут работать с одним и тем же предыдущим состоянием. Правильный подход:

incrementMultiple = () => {
  this.setState(prevState => ({ count: prevState.count + 1 }));
  this.setState(prevState => ({ count: prevState.count + 1 }));
};

Комбинирование состояния с пропсами

Состояние компонента может зависеть от внешних пропсов, но прямое копирование пропсов в состояние не рекомендуется, так как это может привести к рассинхронизации данных. Вместо этого используются эффекты или обработчики:

componentDidUpdate(prevProps) {
  if (prevProps.initialCount !== this.props.initialCount) {
    this.setState({ count: this.props.initialCount });
  }
}

Для функциональных компонентов используется useEffect:

import { useEffect, useState } from 'inferno-hooks';

function Counter({ initialCount }) {
  const [count, setCount] = useState(initialCount);

  useEffect(() => {
    setCount(initialCount);
  }, [initialCount]);

  return <p>{count}</p>;
}

Локальное состояние и производительность

Inferno оптимизирован для минимизации перерисовок. При изменении локального состояния фреймворк:

  • Сравнивает виртуальный DOM с предыдущей версией.
  • Обновляет только изменённые элементы в реальном DOM.
  • Позволяет избежать лишних перерисовок, если состояние не изменилось.

Сложные структуры состояния

Для объектов и массивов важно использовать иммутабельные обновления:

this.setState(prevState => ({
  items: [...prevState.items, newItem]
}));

Это гарантирует корректную работу сравнения виртуального DOM и предотвращает побочные эффекты.

Практические советы

  • Разделять состояние на логические части, чтобы минимизировать влияние на другие части компонента.
  • Использовать функции для обновления состояния при его зависимостях от предыдущего значения.
  • Избегать хранения больших данных или глобальных объектов в локальном состоянии; лучше использовать внешние хранилища или контекст.

Локальное состояние компонентов в Inferno — это мощный инструмент для создания интерактивных пользовательских интерфейсов с высокой производительностью и предсказуемым поведением.