Значения по умолчанию

В библиотеке Haunted для создания веб-компонентов на основе хуков одной из ключевых концепций является управление состоянием компонентов. Значения по умолчанию играют важную роль в инициализации состояний и свойств, обеспечивая предсказуемое поведение компонентов при их рендеринге.

Инициализация состояния с useState

Хук useState позволяет создавать реактивные состояния внутри компонентов. Значение по умолчанию задается непосредственно при вызове хука:

import { html, component } from 'haunted';
import { useState } from 'haunted';

function Counter() {
  const [count, setCount] = useState(0); // Значение по умолчанию: 0

  return html`
    <div>
      <p>Счётчик: ${count}</p>
      <button @click=${() => setCount(count + 1)}>Увеличить</button>
    </div>
  `;
}

customElements.define('my-counter', component(Counter));

Ключевой момент: значение по умолчанию передается одним аргументом в useState и используется только при первом рендере компонента. Любые последующие изменения состояния не переопределяют это значение.

Свойства компонентов и useEffect

Свойства веб-компонентов в Haunted можно определять с помощью геттеров/сеттеров или через объект observedAttributes. Значение по умолчанию для свойства часто задается через инициализацию переменной внутри компонента:

function Greeting({ name = 'Гость' }) { // Значение по умолчанию через деструктуризацию
  return html`<p>Привет, ${name}!</p>`;
}

customElements.define('my-greeting', component(Greeting));

Если компонент получает значение через атрибут, оно автоматически конвертируется в строку, поэтому стоит использовать проверки и fallback к значению по умолчанию:

function InputField({ placeholder }) {
  const safePlaceholder = placeholder || 'Введите текст';
  return html`<input placeholder=${safePlaceholder} />`;
}

customElements.define('my-input', component(InputField));

Ленивая инициализация значений

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

const [data, setData] = useState(() => fetchInitialData());

function fetchInitialData() {
  console.log('Инициализация данных...');
  return { items: [] };
}

Особенность: функция вызывается только один раз при первом рендере. Это позволяет избежать лишних вычислений при каждом обновлении компонента.

Значения по умолчанию для нескольких состояний

Компоненты часто используют несколько состояний одновременно. Для каждого состояния можно задавать индивидуальное значение по умолчанию:

function Form() {
  const [username, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [subscribed, setSubscribed] = useState(false);

  return html`
    <form>
      <input
        placeholder="Имя"
        .value=${username}
        @input=${e => setUsername(e.target.value)}
      />
      <input
        placeholder="Email"
        .value=${email}
        @input=${e => setEmail(e.target.value)}
      />
      <label>
        <input
          type="checkbox"
          .checked=${subscribed}
          @change=${e => setSubscribed(e.target.checked)}
        />
        Подписка
      </label>
    </form>
  `;
}

customElements.define('my-form', component(Form));

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

Влияние значений по умолчанию на повторный рендер

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

const [count, setCount] = useState(10);

function reset() {
  setCount(10); // Явное возвращение к значению по умолчанию
}

Связь с useEffect и вычисляемыми состояниями

Значения по умолчанию тесно связаны с хуком useEffect. Часто требуется выполнить побочные эффекты только после инициализации состояния:

const [user, setUser] = useState(null);

useEffect(() => {
  if (!user) {
    fetch('/api/user')
      .then(res => res.json())
      .then(setUser);
  }
}, []);

Здесь null выступает как значение по умолчанию, сигнализируя о том, что данные ещё не загружены. После получения данных user перестаёт быть null, и компонент рендерится с актуальными значениями.

Практические рекомендации

  • Для примитивов (string, number, boolean) удобно задавать значения по умолчанию прямо при деструктуризации аргументов.
  • Для объектов и массивов лучше использовать ленивую инициализацию через функцию, чтобы избежать общих ссылок между экземплярами компонентов.
  • Значения по умолчанию должны быть согласованы с логикой рендеринга: отсутствие корректного значения может вызвать ошибки или некорректный вывод.

Значения по умолчанию в Haunted создают фундамент для безопасного и предсказуемого поведения компонентов, упрощая работу с состоянием и свойствами. Они обеспечивают ясность, предотвращают ошибки при первом рендере и позволяют грамотно управлять логикой обновлений.