Перейти к содержанию

Атрибут Reactive⚓︎

Атрибут #[Reactive] заставляет свойство дочернего компонента автоматически обновляться, когда родитель изменяет передаваемое значение.

Базовое использование⚓︎

Примените атрибут #[Reactive] к любому свойству, которое должно реагировать на изменения в родительском компоненте:

resources/views/components/⚡todo-count.blade.php
<?php

use Livewire\Attributes\Reactive;
use Livewire\Attributes\Computed;
use Livewire\Component;

new class extends Component {
    #[Reactive]
    public $todos;

    #[Computed]
    public function count()
    {
        return $this->todos->count();
    }
};
?>

<div>
    Количество: {{ $this->count }}
</div>

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

Почему пропсы не реактивны по умолчанию⚓︎

По умолчанию пропсы Livewire не реактивны. Когда родительский компонент обновляется, на сервер отправляется только состояние родителя, а не дочернего компонента. Это минимизирует передачу данных и повышает производительность.

Вот что происходит без #[Reactive]:

resources/views/components/⚡todos.blade.php
<?php

use Livewire\Component;

new class extends Component {
    public $todos = [];

    public function addTodo($text)
    {
        $this->todos[] = ['text' => $text];
        // Дочерние компоненты с пропсами $todos не будут обновляться автоматически
    }
};
?>

<div>
    <livewire:todo-count :$todos />

    <button wire:click="addTodo('Новая задача')">Добавить задачу</button>
</div>

Без #[Reactive] для свойства $todos дочернего компонента добавление задачи в родительском компоненте не приведет к обновлению счётчика в дочернем.

Как это работает⚓︎

Когда вы добавляете #[Reactive]:

  1. Родитель обновляет своё свойство $todos
  2. Родитель отправляет новое значение $todos дочернему компоненту во время ответа
  3. Дочерний компонент автоматически перерендеривается с новым значением

Это создает «реактивную» связь, аналогичную фронтенд-фреймворкам, таким как Vue или React.

Соображения производительности⚓︎

Используйте реактивные свойства экономно

Реактивные свойства требуют передачи дополнительных данных между сервером и клиентом при каждом обновлении родителя. Используйте #[Reactive] только тогда, когда это необходимо для вашей задачи.

Когда использовать:

  • Дочерний компонент отображает данные, которые меняются в родителе
  • Дочерний компонент должен синхронизироваться с состоянием родителя
  • Вы создаете тесно связанную структуру родитель-ребёнок

Когда НЕ использовать:

  • Исходные данные передаются один раз и никогда не меняются
  • Дочерний компонент управляет своим собственным независимым состоянием
  • Производительность имеет решающее значение, а обновления не требуются

Пример: Результаты живого поиска⚓︎

Вот практический пример компонента поиска с реактивными результатами:

resources/views/components/⚡search.blade.php
<?php

use Livewire\Component;
use App\Models\Post;

new class extends Component {
    public $query = '';

    public function posts()
    {
        return Post::where('title', 'like', "%{$this->query}%")->get();
    }
};
?>

<div>
    <input type="text" wire:model.live="query" placeholder="Поиск постов...">

    <livewire:search-results :posts="$this->posts()" />
</div>
resources/views/components/⚡search-results.blade.php
<?php

use Livewire\Attributes\Reactive;
use Livewire\Component;

new class extends Component {
    #[Reactive]
    public $posts;
};
?>

<div>
    @foreach($posts as $post)
        <div wire:key="{{ $post->id }}">{{ $post->title }}</div>
    @endforeach
</div>

Когда пользователь вводит текст, $posts родителя меняются, и результаты в дочернем компоненте автоматически обновляются.

Альтернатива: События⚓︎

Для слабосвязанных компонентов рассмотрите возможность использования событий вместо реактивных пропсов:

<?php

// Родитель отправляет событие
$this->dispatch('todos-updated', todos: $this->todos);

// Дочерний компонент слушает событие
#[On('todos-updated')]
public function handleTodosUpdate($todos)
{
    $this->todos = $todos;
}

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

Узнать больше⚓︎

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