You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel/React/Inertia V2.0 无限滚动分页异常问题求助

Laravel/React/Inertia V2 无限滚动分页重复请求page=2问题解决

问题核心

使用Inertia::merge()和<WhenVisible/>实现无限滚动时,首次加载page=2正常合并数据,但后续触底始终请求page=2,导致重复数据,本质是前端页码状态未正确更新。

错误原因分析

  1. 后端单个值误用Inertia::merge():merge()是为数组/集合合并设计的,对page这类单个数值使用merge()会导致Inertia无法正确替换旧值,前端props中的页码始终停留在初始值。
  2. 完整资源集合合并逻辑错误:直接合并FeatureListResource集合时,Inertia会替换整个集合对象(包括meta),而非仅追加data,导致旧数据丢失且页码追踪失效。

正确实现方案

后端代码修正(FeatureController.php)

只对需要追加的features数据使用merge(),分页元数据直接返回确保替换更新:

<?php
namespace App\Http\Controllers;
use App\Http\Resources\FeatureListResource;
use Inertia\Inertia;
class FeatureController extends Controller
{
    public function index()
    {
        $paginated = Feature::latest()->paginate();
        $resource = FeatureListResource::collection($paginated)->toArray(request());

        return Inertia::render('Feature/Index', [
            // 仅合并数据部分,实现数组追加
            'features' => Inertia::merge(fn() => $resource['data']),
            // 直接返回分页元数据,确保每次请求后更新前端状态
            'pagination' => [
                'current_page' => $paginated->currentPage(),
                'last_page' => $paginated->lastPage(),
            ]
        ]);
    }
}

前端代码修正(Index.tsx)

基于后端返回的分页元数据计算下一页,利用组件props响应式更新自动同步请求参数:

export default function Index({ auth, features, pagination }: PageProps<{ 
    features: Feature[], 
    pagination: { current_page: number, last_page: number } 
}>) {
    const hasMorePages = pagination.current_page < pagination.last_page;

    return (
        <AuthenticatedLayout
            header={
                <h2 className="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
                    Features
                </h2>
            }
        >
            <Head title="Features" />

            {features.map(feature => (
                <FeatureItem key={feature.id} feature={feature} />
            ))}

            {hasMorePages && (
                <WhenVisible
                    always
                    fallback={<div className='text-gray-200'>Loading {pagination.current_page + 1}</div>}
                    params={{
                        data: { page: pagination.current_page + 1 },
                        only: ['features', 'pagination'],
                        preserveUrl: true
                    }}
                >
                    <p className='text-gray-200'>
                        Load page {pagination.current_page + 1}
                    </p>
                </WhenVisible>
            )}
        </AuthenticatedLayout>
    )
}

关键优化点

  1. 精准合并数据:仅对features的data数组使用merge(),保证旧数据不丢失,新数据正常追加。
  2. 响应式页码追踪:分页元数据直接返回,前端props自动更新,<WhenVisible>的请求参数会同步使用最新的current_page + 1。
  3. 终止条件判断:通过current_page < last_page避免无意义的后续请求。

内容的提问来源于stack exchange,提问作者georgleb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:05:01