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