Определение Props

В Stencil, как и в других фреймворках для создания компонентов, props (сокращение от “properties”) играют важную роль в передаче данных между компонентами. Props — это входные параметры компонента, которые задаются извне, позволяя компонентам быть динамичными и настраиваемыми. Они позволяют компоненту получать информацию из родительского компонента и использовать эти данные в своей внутренней логике.

Создание и использование Props

Для того чтобы объявить props в Stencil, используется декоратор @Prop(). Он позволяет компоненту принимать данные извне, что делает его гибким и переиспользуемым. Объявление prop выглядит следующим образом:

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

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Prop() name: string;

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}

В примере выше компонент MyComponent имеет prop name, который используется внутри метода render для отображения приветственного сообщения. Такой подход позволяет компоненту быть гибким и изменять свое поведение в зависимости от значения prop.

Типы данных для Props

Props могут принимать различные типы данных. Это могут быть строки, числа, массивы, объекты, булевы значения, а также сложные структуры, такие как функции или другие компоненты. В Stencil типизация поддерживается с использованием TypeScript, что позволяет указать тип props для более строгой проверки на этапе разработки.

Пример с числовым prop:

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

@Component({
  tag: 'counter-component',
  styleUrl: 'counter-component.css',
  shadow: true,
})
export class CounterComponent {
  @Prop() count: number;

  render() {
    return <div>Current count: {this.count}</div>;
  }
}

В этом примере prop count будет ожидать число. В случае если родительский компонент передаст значение другого типа, TypeScript выдаст ошибку на этапе компиляции.

Дефолтные значения и валидаторы для Props

Props в Stencil могут иметь значения по умолчанию, если они не были переданы родительским компонентом. Для задания дефолтного значения используется свойство defaultValue.

Пример с дефолтным значением:

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

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Prop() name: string = 'Guest';

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}

Здесь prop name по умолчанию будет иметь значение 'Guest', если родительский компонент не передаст свойство name.

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

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

@Component({
  tag: 'email-component',
  styleUrl: 'email-component.css',
  shadow: true,
})
export class EmailComponent {
  @Prop() email: string;

  componentWillLoad() {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(this.email)) {
      console.error('Invalid email format');
    }
  }

  render() {
    return <div>{this.email}</div>;
  }
}

В этом примере используется регулярное выражение для проверки формата email-адреса. Если значение email не соответствует формату, выводится ошибка.

Связь между Props и State

Props и state компонента — два ключевых механизма для хранения данных и их передачи в Stencil. Props служат для передачи данных извне, в то время как state хранит данные, которые изменяются в пределах компонента.

Props являются неизменяемыми (immutable) в рамках компонента, что означает, что компонент не должен изменять их напрямую. Если нужно обновить данные внутри компонента, следует использовать state, который можно изменять.

Пример использования props и state:

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

@Component({
  tag: 'toggle-component',
  styleUrl: 'toggle-component.css',
  shadow: true,
})
export class ToggleComponent {
  @Prop() initialState: boolean;
  @State() isToggled: boolean = this.initialState;

  toggle() {
    this.isToggled = !this.isToggled;
  }

  render() {
    return (
      <div>
        <button onCl ick={() => this.toggle()}>Toggle</button>
        <p>The state is: {this.isToggled ? 'ON' : 'OFF'}</p>
      </div>
    );
  }
}

В этом примере prop initialState задается извне, а state isToggled отслеживает текущее состояние компонента. При каждом клике на кнопку состояние меняется, что иллюстрирует, как props и state могут работать вместе.

Наблюдение за изменениями Props

Stencil предоставляет возможность реагировать на изменения props с помощью хука componentWillUpdate. Этот хук вызывается перед обновлением компонента, что позволяет отслеживать изменения значений props и выполнять нужные действия.

Пример:

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

@Component({
  tag: 'watch-prop-component',
  styleUrl: 'watch-prop-component.css',
  shadow: true,
})
export class WatchPropComponent {
  @Prop() name: string;

  componentWillUpdate() {
    console.log(`The prop "name" is about to change to: ${this.name}`);
  }

  render() {
    return <div>Hello, {this.name}!</div>;
  }
}

В этом примере перед каждым обновлением компонента выводится сообщение о предстоящем изменении значения prop name.

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

  • Повторное использование компонентов: Props позволяют компонентам быть гибкими и многократно используемыми. Компонент может изменять свое поведение в зависимости от того, какие данные ему передаются через props.
  • Чистота и модульность кода: Каждый компонент может быть изолирован и настроен с помощью props, что делает код более организованным и легко поддерживаемым.
  • Производительность: Благодаря тому, что props являются неизменяемыми, Stencil эффективно отслеживает изменения и обновляет только те компоненты, которые действительно изменились.

Props играют ключевую роль в создании динамичных и настраиваемых компонентов в Stencil. Использование этого механизма позволяет улучшить гибкость и производительность приложения, а также сделать код более читаемым и поддерживаемым.