Статьи и новости

Livewire: фикс ошибки Snapshot missing on Livewire component with id

Суть темы: есть компонент, который рендерит несколько дочерних компонентов по условию, в зависимости от типа модели. Вот так:

<div class="max-w-4xl mx-auto mb-12">
    @foreach($materials as $material)
        @if ($material instanceof MaterialAudio)
            <livewire:material-audio-editor :material="$material" wire:key="{{ $material->uuid }}" />
    @elseif($material instanceof MaterialVideo)
           <livewire:material-video-editor :material="$material" wire:key="{{ $material->uuid }}" />
    @endif
    @endforeach
</div>

Вроде бы все хорошо, но если внутри дочернего компонента послать родителю событие «Удали меня» и перезагрузить список доступных материалов, произойдет нечто неожиданное:

Snapshot missing on Livewire component with id

Это то, что вы увидите в консоли.

Фикс очень прост, хотя для того, чтобы его найти, пришлось потратить больше 2х часов:

Оберните все, что внутри цикла @foreach, в div, содержащий постоянный ключ (т.е. не рандомный!). Отлично подойдет id модели текущей итерации цикла @foreach.

Вот так:

<div class="max-w-4xl mx-auto mb-12">
    @foreach($materials as $material)
        {{-- !!! Важно !!! --}}
        <div class="key-wrapper" wire:key="{{ $material->type . '-' . $material->uuid }}">
            @if ($material instanceof MaterialAudio)
                <livewire:material-audio-editor :material="$material" wire:key="{{ $material->uuid }}"/>
            @elseif ($material instanceof MaterialVideo)
                <livewire:material-video-editor :material="$material" wire:key="{{ $material->uuid }}"/>
            @endif
        </div>
    @endforeach
</div>

Все дело в том, что если пытаться привязать wire:key (или key, или :key, или выпускать key или wire:key непосредственно в дочернем компоненте), это не отрендерит на корневом элементе нужный нам wire:key. В документации об этом молчат. В общем, пользуйтесь.

Ваш комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *