Render функции

Render функции в Stencil представляют собой центральный механизм формирования DOM-компонентов на основе состояния и свойств. Они дают полный контроль над структурой и содержимым элемента, заменяя шаблонный синтаксис JSX, если требуется динамическая генерация элементов на основе сложной логики.

Основы использования

Render функция определяется внутри класса компонента и возвращает виртуальный DOM, созданный с помощью JSX. Ключевой особенностью является то, что возвращаемый JSX транслируется в оптимизированные вызовы h(), которые Stencil использует для обновления реального DOM.

import { Component, h, Prop, State } from '@stencil/core';

@Component({
  tag: 'my-counter',
  styleUrl: 'my-counter.css',
  shadow: true,
})
export class MyCounter {
  @State() count: number = 0;

  increment() {
    this.count += 1;
  }

  render() {
    return (
      <div>
        <p>Текущее значение: {this.count}</p>
        <button onCl ick={() => this.increment()}>Увеличить</button>
      </div>
    );
  }
}

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

  • render() всегда возвращает JSX-элемент или массив элементов.
  • Изменение состояния через @State автоматически вызывает повторный рендер.
  • Атрибуты DOM можно задавать через стандартный JSX-синтаксис.

Условный рендеринг

Stencil позволяет управлять видимостью элементов на основе условий, используя стандартные конструкции Jav * aScript:

render() {
  return (
    <div>
      {this.count > 0 ? <p>Положительное значение: {this.count}</p> : <p>Счетчик равен нулю</p>}
      <button onCl ick={() => this.increment()}>Увеличить</button>
    </div>
  );
}

Важно помнить, что JSX-выражения должны быть валидными элементами или null, чтобы избежать ошибок рендеринга.

Рендеринг списков

Для динамического создания элементов на основе массива применяется метод map:

@State() items: string[] = ['Яблоко', 'Банан', 'Вишня'];

render() {
  return (
    <ul>
      {this.items.map(item => (
        <li>{item}</li>
      ))}
    </ul>
  );
}

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

  • Каждый элемент списка может иметь уникальный key, особенно при динамическом изменении массива.
  • Использование map в JSX позволяет легко интегрировать данные с любыми источниками состояния.

События и обработчики

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

<button onCl ick={() => this.handleClick()}>Кликни меня</button>
  • Для улучшения производительности рекомендуется использовать привязку методов класса вместо создания новых функций на каждом рендере.
  • Можно передавать параметры через стрелочные функции, если требуется контекст или дополнительные данные.

Комбинирование с Shadow DOM и слотом

Stencil интегрирует Render функции с Shadow DOM и <slot> для реализации составных компонентов:

render() {
  return (
    <div class="wrapper">
      <slot name="header"></slot>
      <p>Основное содержимое компонента</p>
      <slot name="footer"></slot>
    </div>
  );
}
  • Использование <slot> позволяет гибко комбинировать статическое и динамическое содержимое.
  • Shadow DOM изолирует стили, но Render функция может комбинировать внутренние элементы с внешними слотами.

Оптимизация производительности

Stencil применяет виртуальный DOM и умные диффы для минимизации обновлений реального DOM. Для высоконагруженных компонентов рекомендуется:

  • Минимизировать количество логики внутри render().
  • Использовать @State и @Prop только для тех данных, которые влияют на отображение.
  • Выносить тяжелые вычисления в методы класса и вызывать их внутри JSX.

Вложенные компоненты

Render функции позволяют строить иерархию компонентов, поддерживая повторное использование и модульность:

render() {
  return (
    <div>
      <my-header></my-header>
      <main>
        {this.items.map(item => (
          <my-item content={item}></my-item>
        ))}
      </main>
      <my-footer></my-footer>
    </div>
  );
}
  • Компоненты, используемые внутри JSX, автоматически связываются с жизненным циклом Stencil.
  • Props передаются стандартным образом, а изменения состояния вызывают обновление дочерних компонентов при необходимости.

Заключение по функциональности

Render функции предоставляют максимальную гибкость для построения компонентов. Их возможности включают:

  • Полное управление DOM.
  • Условное отображение и рендеринг списков.
  • Обработку событий.
  • Интеграцию с Shadow DOM и слотами.
  • Создание динамических и вложенных компонентов.

Правильное использование render функций позволяет создавать сложные, интерактивные и высокопроизводительные веб-компоненты в Stencil.