开发者问题收集

未捕获(在承诺中)TypeError:无法读取 null 的属性(读取“指纹”)Laravel Livewire

2021-12-06
11482

我使用 Laravel Livewire 制作了一个多文件上传组件。上传完成后,我想显示已上传的文件而不重新加载页面,如下所示:

<div class="grid grid-flow-col auto-cols-max gap-4 mb-5">
    @foreach ($files as $file)
        <livewire:file :file="$file"/>
    @endforeach
</div>

一次上传一个或多个文件可以正常工作。但是在上传时,如果循环中已经存在文件,Livewire 会抛出此错误: Uncaught (in promise) TypeError: Cannot read properties of null (reading 'fingerprint')

经过一番研究,我得出结论,这是因为 Livewire 生成了与第一个文件相同的 id:

<div class="grid grid-flow-col auto-cols-max gap-4 mb-5">               
    <div wire:id="eCHZ9wxyp7nxOC4o5uCC" class="file file-jpeg file-lg">
        <!-- content of existing file component -->
    </div>
                     
    <div wire:id="eCHZ9wxyp7nxOC4o5uCC" class="file file-jpeg file-lg">
        <!-- content of new file component, should have Unique wire:id -->
    </div>        
</div>

如何解决这个问题?

3个回答

该问题最早出现在 2020 年 9 月,现已解决(参考: https://github.com/livewire/livewire/issues/1686 )。发生该错误的原因是新文件与现有文件不唯一。 Github 上提到的解决方案有效,但已经过时了。

如果你使用的是 Laravel 7 或更高版本,则可以在循环内的 livewire 组件中添加 :wire:key="$yourUniqueKey"

<div class="grid grid-flow-col auto-cols-max gap-4 mb-5">
    @foreach ($files as $file)
        <livewire:file :file="$file" :wire:key="$file->id"/>
    @endforeach
</div>

参考: https://laravel-livewire.com/docs/2.x/nesting-components

另请检查 https://laravel-livewire.com/docs/2.x/troubleshooting#dom-diffing-issues ,特别是这个部分:

The value you pass to wire:key must be entirely unique to that page. Meaning that you should prefix it, like wire:key="item-{{ $item->id }}" , and avoid using $loop->index to track the individual elements where you can.

Dirk Jan
2021-12-06

我通过在关键变量中传递时间来解决这个问题

<div class="grid grid-flow-col auto-cols-max gap-4 mb-5">
    @foreach ($files as $file)
        <livewire:file :file="$file" :wire:key="time().$file->id"/>
    @endforeach
</div>
Albukheity Soft
2023-01-23

我在多个组件上遇到了同样的问题,并通过向密钥 ID 添加字符串解决了这个问题,就我的情况而言:

@foreach ($data1s as $data)

<livewire:data1 :data="$data" :wire:key="'data1'.$data->id"/>

@endforeach

@foreach ($data2s as $data)

<livewire:data2 :data="$data" :wire:key="'data2'.$data->id"/>

@endforeach

Jhordy Barrera
2023-04-18