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

Условный рендеринг — это техника, позволяющая динамически изменять отображение компонентов в зависимости от определённых условий. В Stencil, как и в других фреймворках, эта концепция применяется для управления тем, какие элементы или компоненты должны отображаться на странице в конкретный момент времени. Это может быть полезно в случаях, когда нужно изменить интерфейс в ответ на действия пользователя, загрузку данных или состояние приложения.

Условные выражения в JSX

Stencil использует JSX, который является синтаксическим расширением для JavaScript, для описания UI-компонентов. Внутри JSX можно использовать обычные JavaScript-выражения, включая условные операторы.

Для выполнения простого условия достаточно использовать оператор && или тернарный оператор. Оба варианта позволяют выполнять рендеринг элемента или компонента, если условие истинно.

Пример с использованием оператора &&

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

@Component({
  tag: 'app-example',
  styleUrl: 'app-example.css',
  shadow: true
})
export class AppExample {
  @State() isVisible: boolean = false;

  render() {
    return (
      <div>
        {this.isVisible && <p>Элемент отображается</p>}
        <button onCl ick={() => this.isVisible = !this.isVisible}>
          Показать/Скрыть
        </button>
      </div>
    );
  }
}

В этом примере параграф с текстом будет отображаться только в случае, если свойство isVisible истинно. При изменении состояния компонента кнопка будет переключать видимость элемента.

Пример с использованием тернарного оператора

render() {
  return (
    <div>
      <p>{this.isVisible ? 'Элемент отображается' : 'Элемент скрыт'}</p>
      <button onCl ick={() => this.isVisible = !this.isVisible}>
        Показать/Скрыть
      </button>
    </div>
  );
}

Здесь используется тернарный оператор для вывода разных сообщений в зависимости от значения isVisible.

Рендеринг различных компонентов

В Stencil можно не только изменять отображение элементов, но и рендерить различные компоненты в зависимости от состояния. Например, можно показать один компонент при выполнении условия и другой — при его невыполнении.

Пример с условным рендерингом компонентов

import { Component, h, State } from '@stencil/core';
import { LoadingComponent } from './loading-component';
import { ContentComponent } from './content-component';

@Component({
  tag: 'app-condition-rendering',
  styleUrl: 'app-condition-rendering.css',
  shadow: true
})
export class AppConditionRendering {
  @State() isLoading: boolean = true;

  render() {
    return (
      <div>
        {this.isLoading ? <LoadingComponent /> : <ContentComponent />}
        <button onCl ick={() => this.isLoading = !this.isLoading}>
          Показать/Скрыть контент
        </button>
      </div>
    );
  }
}

В этом примере компонент LoadingComponent будет отображаться, пока переменная isLoading истинна. Как только состояние изменится, вместо загрузочного компонента появится ContentComponent.

Условный рендеринг с использованием методов

Иногда бывает полезно использовать вспомогательные методы для более сложных условий. Это позволяет улучшить читаемость кода и избежать нагромождения логики в JSX.

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

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

@Component({
  tag: 'app-conditional-method',
  styleUrl: 'app-conditional-method.css',
  shadow: true
})
export class AppConditionalMethod {
  @State() isAuthenticated: boolean = false;

  checkAuthStatus() {
    return this.isAuthenticated ? <p>Добро пожаловать!</p> : <p>Пожалуйста, войдите в систему</p>;
  }

  render() {
    return (
      <div>
        {this.checkAuthStatus()}
        <button onCl ick={() => this.isAuthenticated = !this.isAuthenticated}>
          Войти/Выйти
        </button>
      </div>
    );
  }
}

В этом примере метод checkAuthStatus возвращает условное содержимое, которое зависит от состояния isAuthenticated.

Рендеринг с использованием асинхронных данных

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

Пример с асинхронным условным рендерингом

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

@Component({
  tag: 'app-async-rendering',
  styleUrl: 'app-async-rendering.css',
  shadow: true
})
export class AppAsyncRendering {
  @State() data: any = null;

  async componentWillLoad() {
    const response = await fetch('https://api.example.com/data');
    this.data = await response.json();
  }

  render() {
    return (
      <div>
        {this.data ? (
          <div>
            <h1>{this.data.title}</h1>
            <p>{this.data.description}</p>
          </div>
        ) : (
          <p>Загрузка...</p>
        )}
      </div>
    );
  }
}

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

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

Иногда требуется отобразить список элементов, где каждый элемент рендерится на основе условий. В Stencil можно использовать JavaScript-циклы, такие как map(), в сочетании с условными операторами для рендеринга сложных списков.

Пример с циклом и условным рендерингом

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

@Component({
  tag: 'app-item-list',
  styleUrl: 'app-item-list.css',
  shadow: true
})
export class AppItemList {
  @State() items: string[] = ['Item 1', 'Item 2', 'Item 3'];
  @State() showItems: boolean = true;

  render() {
    return (
      <div>
        {this.showItems ? (
          <ul>
            {this.items.map(item => <li>{item}</li>)}
          </ul>
        ) : (
          <p>Список скрыт</p>
        )}
        <button onCl ick={() => this.showItems = !this.showItems}>
          Показать/Скрыть элементы
        </button>
      </div>
    );
  }
}

Здесь для каждого элемента из массива items генерируется список. Если условие showItems истинно, отображается список, иначе — сообщение о том, что список скрыт.

Заключение

Условный рендеринг в Stencil является мощным инструментом для динамического изменения интерфейса в зависимости от состояния компонента или внешних факторов. Он предоставляет разработчикам гибкость для создания интерактивных и отзывчивых приложений, которые могут адаптироваться к различным условиям и состояниям.