Суть темы: есть компонент, который рендерит несколько дочерних компонентов по условию, в зависимости от типа модели. Вот так:
<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. В документации об этом молчат. В общем, пользуйтесь.