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

分页切换时骨架屏不显示及页面切换延迟问题排查

解决方案

问题1:分页切换无PLPSkeleton骨架屏显示

服务端组件(SC)在query参数变化时,Next.js会默认等待数据加载完成后才渲染新内容,无法直接在SC内实现加载状态,可通过以下两种方式解决:

方式1:利用路由段loading.js

在app/category目录下创建客户端组件loading.js,作为该路由的加载占位符:

// app/category/loading.js
'use client';

import PLPSkeleton from '@/components/PLPSkeleton';

export default function CategoryLoading() {
  return <PLPSkeleton />;
}

当分页query变化触发服务端组件重新获取数据时,Next.js会自动渲染loading.js内容,直到数据加载完成。

方式2:客户端组件包裹分页与列表

将分页组件和商品列表外层改为客户端组件,借助useRouter的isPending状态控制骨架屏显示:

// app/category/ProductListWrapper.jsx
'use client';

import { useRouter, useSearchParams } from 'next/navigation';
import PLPSkeleton from '@/components/PLPSkeleton';
import ProductList from './ProductList'; // 原服务端组件提取的商品列表部分

export default function ProductListWrapper() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const currentPage = searchParams.get('page') || '1';

  if (router.isPending) {
    return <PLPSkeleton />;
  }

  return <ProductList page={currentPage} />;
}

随后在app/category/page.js中引入该客户端组件:

// app/category/page.js
import ProductListWrapper from './ProductListWrapper';

export default async function CategoryPage({ searchParams }) {
  return <ProductListWrapper />;
}

问题2:分页切换URL更新延迟

当前问题源于服务端组件的导航逻辑等待API请求完成后才更新URL,需改为客户端侧触发路由跳转,先更新URL再加载数据:

修改分页组件为客户端组件

确保分页按钮在客户端组件中,使用useRouter的push方法直接跳转,无需等待API响应:

// components/Pagination.jsx
'use client';

import { useRouter, useSearchParams } from 'next/navigation';

export default function Pagination({ totalPages }) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const currentPage = parseInt(searchParams.get('page') || '1');

  const handlePageChange = (page) => {
    if (page < 1 || page > totalPages) return;
    
    const newSearchParams = new URLSearchParams(searchParams);
    newSearchParams.set('page', page.toString());
    router.push(`?${newSearchParams.toString()}`);
  };

  return (
    <div className="pagination">
      {Array.from({ length: totalPages }, (_, i) => i + 1).map(page => (
        <button
          key={page}
          onClick={() => handlePageChange(page)}
          className={currentPage === page ? 'active' : ''}
        >
          {page}
        </button>
      ))}
    </div>
  );
}

点击分页按钮时URL会立即更新,同时触发服务端组件重新获取对应页数据,结合骨架屏方案即可实现先更新URL再显示加载状态的效果。

配套服务端组件调整

确保服务端组件能根据searchParams的page参数调用接口:

// app/category/ProductList.jsx(服务端组件)
import { getCategoryProducts } from '@/api/products';

export default async function ProductList({ page }) {
  const products = await getCategoryProducts({ page: parseInt(page) });
  return (
    <div className="product-list">
      {products.map(product => (
        <div key={product.id} className="product-card">
          {/* 商品内容 */}
        </div>
      ))}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:32:49