Next.js 14 App Router排序+无限滚动的规范实现方案问询
解决方案
核心问题是useFormState的初始状态仅在组件首次挂载时生效,后续URL参数变化导致initialData更新时,不会自动重置内部状态。我们可以通过在客户端组件中监听查询参数变化,手动同步状态来解决。
步骤1:修改客户端组件,添加状态同步逻辑
在ClientComponent.jsx中,使用useSearchParams获取当前URL的排序参数,结合useEffect监听initialData的变化,当排序方式变更时,手动重置本地状态:
"use client" import { useState, useEffect, useTransition } from 'react'; import Link from 'next/link'; export default function ClientComponent({ initialData, fetchNextPage }) { // 用本地状态管理数据,替代直接依赖useFormState的返回值 const [dataState, setDataState] = useState(initialData); const [isPending, startTransition] = useTransition(); // 监听initialData变化(URL参数变更时由Server Component传递) useEffect(() => { // 当排序方向变化时,重置本地状态为新的initialData if (initialData.meta.sortDir !== dataState.meta.sortDir) { setDataState(initialData); } }, [initialData, dataState.meta.sortDir]); // 加载更多逻辑:调用Server Action并更新状态 const handleLoadMore = () => { startTransition(async () => { const newState = await fetchNextPage(dataState); setDataState(newState); }); }; const { data, meta } = dataState; return ( <div> <Link href={{ query: { sortDir: meta.sortDir === 'asc' ? 'desc' : 'asc' } }}> Sort {meta.sortDir === 'asc' ? 'desc' : 'asc'} </Link> {/* 数据展示区域 */} <ul> {data.map(item => ( <li key={item.id}>{item.content}</li> ))} </ul> {meta.hasNextPage && ( <button onClick={handleLoadMore} disabled={isPending}> {isPending ? 'Loading...' : 'Load more'} </button> )} </div> ); }
步骤2:保留Server Component和Server Action逻辑
page.jsx的代码无需修改,它已经能根据URL查询参数正确获取初始数据并传递给客户端组件:
async function fetchNextPage(currentState) { "use server" const { data, meta } = currentState; const response = await fetch( `/api/data?offset=${meta.offset + meta.limit}&sortDir=${meta.sortDir}` ).then(res => res.json()); return { data: [...data, ...response.data], meta: response.meta, }; } export default async function ServerComponent({ searchParams }) { const initialData = await fetch( `/api/data?offset=0&sortDir=${searchParams.sortDir ?? "asc"}` ).then(res => res.json()); return <ClientComponent initialData={initialData} fetchNextPage={fetchNextPage} />; }
方案说明
- 状态同步:通过
useEffect监听initialData的排序方向变化,一旦URL参数切换了排序方式,就将本地状态重置为Server Component传递的新初始数据,确保显示内容与当前URL匹配。 - 加载状态管理:使用
useTransition处理加载更多的异步操作,避免UI阻塞,并显示加载状态。 - Server Actions规范:保留了Server Action处理分页数据的逻辑,符合Next.js 14的Server Components + Server Actions架构要求。
内容的提问来源于stack exchange,提问作者Moses
相关产品推荐
相关产品推荐

