Laravel Livewire生产环境下列表元素重复渲染两次问题求助
生产环境Laravel Livewire列表元素重复渲染问题排查
我将应用上传到生产服务器后遇到了li元素显示异常的问题,本地Docker环境下一切运行正常。
这是我本地环境的列表效果:
部署到Ubuntu上的Nginx服务后,列表效果如下:
每个元素都重复出现了2次。
我参照相关教程搭建了Ubuntu服务器,随后参照Laravel官方文档优化了缓存配置。
我也检查了MySQL迁移后的数据,确认数据库中不存在重复数据。
所有排查项均显示正常:
Livewire组件ArticlesList.php代码片段:
public function render() { return view('livewire.dashboard.articles-list', [ 'articles' => Article::query() ->search($this->search) ->producer($this->selectedProducer) ->filterBy($this->filter) ->orderBy('hcode') ->orderBy('style') ->paginate($this->perPage) ]); }
视图文件articles-list.blade.php代码片段:
<ul class="divide-y divide-gray-200"> @forelse($articles as $article) <li wire:key="article-{{ $article->hcode }}.{{ $article->style }}" class="relative"> <div class="{{ $selectedArticleId === $article->id ? 'bg-blue-200' : 'hover:bg-gray-100' }} focus-within:ring-2 focus-within:ring-inset focus-within:ring-gray-500"> <div class="flex-1 min-w-0"> <a href="#" wire:click.prevent="selectedArticle({{ $article->id }})" class="block px-4 py-2 focus:outline-none"> <p class="block text-sm font-bold text-gray-800"> {{ $article->fullStyle }} </p> <p class="text-sm text-gray-500 truncate"> {{ $article->description }} </p> </a> </div> </div> </li> @empty <li class="text-center">¯\_(ツ)_/¯</li> @endforelse </ul>
我已经为每个li元素设置了wire:key属性:
我的项目运行环境为:Laravel v8.49、Livewire ^2.5,服务器环境为Ubuntu 20.04、Nginx 1.18、PHP 8.0-fpm。
目前我找不到问题根源,求帮忙排查解决。
排查解决步骤
- 清理生产端所有缓存
本地Docker环境每次启动都是全新缓存,而生产环境部署后必须手动清理各类缓存,执行以下命令:
php artisan cache:clear php artisan view:clear php artisan route:clear php artisan livewire:clear-cache
多数重复渲染问题都是因为旧的视图、组件缓存没有清理导致。
- 修正wire:key取值
你当前使用hcode + style作为wire:key,如果这两个字段存在特殊字符、空格或者生产环境编码兼容问题,会导致Livewire识别key重复,进而重复渲染元素。替换为绝对唯一的主键ID即可:
<li wire:key="article-{{ $article->id }}" class="relative">
- 排查查询语句是否返回重复数据
你检查了数据库原生数据无重复,但如果search、producer、filterBy这几个本地作用域中存在join关联操作,关联表有多条匹配记录时,会返回重复的主表数据,本地数据量少可能未触发该问题。
可以在查询构造器中添加distinct()去重,测试是否解决问题:
'articles' => Article::query() ->distinct() ->search($this->search) ->producer($this->selectedProducer) ->filterBy($this->filter) ->orderBy('hcode') ->orderBy('style') ->paginate($this->perPage)
也可以临时在render方法中打印查询结果ID,确认是否存在重复:
dd($articles->pluck('id')->toArray());
确认依赖版本一致性
检查本地和生产环境的Livewire版本是否一致,确保你将composer.lock提交到了代码仓库,生产部署时执行composer install而非composer update,避免版本差异带来的未知bug。检查模板嵌套逻辑
确认外层布局文件没有重复写@yield或者组件嵌套了两次,生产环境开启模板缓存后,这类笔误更容易触发重复渲染问题。
内容的提问来源于stack exchange,提问作者Greg Ostry
相关产品推荐
相关产品推荐

