Условный рендеринг — это техника, позволяющая динамически изменять отображение компонентов в зависимости от определённых условий. В Stencil, как и в других фреймворках, эта концепция применяется для управления тем, какие элементы или компоненты должны отображаться на странице в конкретный момент времени. Это может быть полезно в случаях, когда нужно изменить интерфейс в ответ на действия пользователя, загрузку данных или состояние приложения.
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 является мощным инструментом для динамического изменения интерфейса в зависимости от состояния компонента или внешних факторов. Он предоставляет разработчикам гибкость для создания интерактивных и отзывчивых приложений, которые могут адаптироваться к различным условиям и состояниям.