Атрибут Reactive⚓︎
Атрибут #[Reactive] заставляет свойство дочернего компонента автоматически обновляться, когда родитель изменяет передаваемое значение.
Базовое использование⚓︎
Примените атрибут #[Reactive] к любому свойству, которое должно реагировать на изменения в родительском компоненте:
<?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]:
<?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]:
- Родитель обновляет своё свойство
$todos - Родитель отправляет новое значение
$todosдочернему компоненту во время ответа - Дочерний компонент автоматически перерендеривается с новым значением
Это создает «реактивную» связь, аналогичную фронтенд-фреймворкам, таким как Vue или React.
Соображения производительности⚓︎
Используйте реактивные свойства экономно
Реактивные свойства требуют передачи дополнительных данных между сервером и клиентом при каждом обновлении родителя. Используйте #[Reactive] только тогда, когда это необходимо для вашей задачи.
Когда использовать:
- Дочерний компонент отображает данные, которые меняются в родителе
- Дочерний компонент должен синхронизироваться с состоянием родителя
- Вы создаете тесно связанную структуру родитель-ребёнок
Когда НЕ использовать:
- Исходные данные передаются один раз и никогда не меняются
- Дочерний компонент управляет своим собственным независимым состоянием
- Производительность имеет решающее значение, а обновления не требуются
Пример: Результаты живого поиска⚓︎
Вот практический пример компонента поиска с реактивными результатами:
<?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>
<?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;
}
События обеспечивают большую гибкость, но требуют явного взаимодействия между компонентами.
Узнать больше⚓︎
Для получения дополнительной информации о взаимодействии родительских и дочерних компонентов и архитектуре компонентов см. документацию по вложенным компонентам.