Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як виконати дію без повторного рендеру компонента: #[Renderless] і skipRender()?

Після кожної дії Livewire за замовчуванням рендерить шаблон компонента заново й відправляє HTML у браузер. Для дій, що нічого не змінюють на екрані, це зайва робота: виконання Blade, обчислювані властивості й запити в шаблоні, розмір відповіді, морфінг DOM.

#[Renderless] - дія без рендеру:

use Livewire\Attributes\Renderless;

new class extends Component {
    public Post $post;

    #[Renderless]
    public function trackRead(): void
    {
        $this->post->increment('reads');
    }
};
<div wire:intersect.once="trackRead">...</div>

Інші способи:

  • $this->skipRender() усередині методу - коли рендер треба пропустити за умовою:
public function saveDraft(): void
{
    $this->post->update(['draft' => $this->draft]);

    if (! $this->showSavedAt) {
        $this->skipRender();   // показувати нічого не треба - рендер зайвий
    }
}
  • модифікатор .renderless у шаблоні - точково, без зміни класу: wire:click.renderless="trackClick", wire:model.live.renderless="draft".

Типові застосування:

  • аналітика й лічильники (перегляди, кліки, час на сторінці);
  • збереження чернетки чи налаштувань, які вже відображені в браузері (стан у полі чи в Alpine);
  • дії, результат яких обробляє JavaScript (повернене значення з await $wire.method()).

Пастки:

  • зміни властивостей у такій дії не з'являться на екрані - шаблон не рендерився. Якщо дія змінює те, що показується, рендер потрібен;
  • помилки валідації в дії без рендеру теж не відобразяться через @error - для таких випадків потрібен рендер чи обробка в JavaScript;
  • стан компонента все одно оновлюється - новий знімок повертається в браузер, тож наступні дії бачитимуть змінені значення.

Поєднання з #[Async] - класична пара для «запустив і забув»: дія не стає в чергу за іншими й не перемальовує компонент.

Тести: ->call('trackRead')->assertRenderSkipped().

Докладніше в документації: Атрибут Renderless

Схожі питання