Next.js 13.2 Beta:如何在服务器组件中为查询传递过滤器?
Next.js 13.2 Beta 服务器组件数据过滤方案建议
针对你在服务器组件中过滤数据并供多组件复用的需求,以下是几个无需依赖客户端组件的可行方案:
方案一:在根服务器组件中提前过滤,传递给子组件
直接在Home这类根服务器组件中完成数据获取与过滤,将处理后的结果通过props传递给所有需要的子组件。这种方式逻辑简单,所有数据处理都在服务器端完成,完全适配你的需求。
修正后的示例代码:
export default async function Home() { // 获取原始数据 const artists = await GetAllArtists(); const rawVenues = await GetAllVenues(); // 服务器端过滤逻辑示例:筛选位于特定城市的场馆 const filteredVenues = rawVenues.filter(venue => venue.city === "New York"); return ( <main className="mx-auto flex flex-col justify-center items-center"> {/* 传递过滤后的数据给地图组件 */} <ViewMap venues={filteredVenues} /> <div> <section className="p-5"> <h2 className="text-2xl font-bold p-4">Artists</h2> <Suspense fallback={<ArtistSkeleton />}> {artists && <ShowArtists artists={artists} />} </Suspense> </section> <section className="p-5"> <h2 className="text-2xl font-bold p-4">Venues</h2> <Suspense fallback={<p>Loading venues...</p>}> {/* 传递过滤后的数据给场馆列表组件 */} {filteredVenues && <Venues venues={filteredVenues} />} </Suspense> </section> </div> </main> ); }
方案二:封装复用的服务器端过滤函数
如果过滤逻辑需要在多个服务器组件中复用,可以将过滤逻辑封装成独立的异步函数(兼容Prisma的异步查询),在需要的组件中调用后传递数据。
示例:
// 工具函数文件:lib/filters.ts export async function getFilteredVenues(filterCondition: { city?: string }) { const rawVenues = await GetAllVenues(); // 执行过滤逻辑 return rawVenues.filter(venue => { if (filterCondition.city) { return venue.city === filterCondition.city; } return true; }); } // 在Home组件中使用 export default async function Home() { const artists = await GetAllArtists(); const filteredVenues = await getFilteredVenues({ city: "New York" }); return ( // 同方案一的渲染逻辑,传递filteredVenues给子组件 ); }
方案三:创建专用服务器组件作为数据提供者
如果需要在多层级的服务器组件中共享过滤后的数据,可以创建一个专门的服务器组件,负责数据获取、过滤,并将结果传递给子组件树。
示例:
// 服务器组件:components/FilteredVenuesProvider.tsx export default async function FilteredVenuesProvider({ children, filter, }: { children: React.ReactNode; filter: { city?: string }; }) { const rawVenues = await GetAllVenues(); const filteredVenues = rawVenues.filter(venue => filter.city ? venue.city === filter.city : true ); // 将过滤后的数据传递给子组件 return React.Children.map(children, child => { if (React.isValidElement(child)) { return React.cloneElement(child, { venues: filteredVenues }); } return child; }); } // 在Home组件中使用 export default async function Home() { const artists = await GetAllArtists(); return ( <FilteredVenuesProvider filter={{ city: "New York" }}> <main className="mx-auto flex flex-col justify-center items-center"> <ViewMap /> {/* 自动接收filteredVenues props */} <div> <section className="p-5"> <h2 className="text-2xl font-bold p-4">Artists</h2> <Suspense fallback={<ArtistSkeleton />}> {artists && <ShowArtists artists={artists} />} </Suspense> </section> <section className="p-5"> <h2 className="text-2xl font-bold p-4">Venues</h2> <Suspense fallback={<p>Loading venues...</p>}> <Venues /> {/* 自动接收filteredVenues props */} </Suspense> </section> </div> </main> </FilteredVenuesProvider> ); }
额外提示:
- 你提供的代码存在两处问题:重复声明
venues变量、data未定义,建议修正后再使用。 - 若需要动态过滤(比如基于用户筛选条件),可以读取服务器组件的
searchParams参数,根据参数执行对应过滤逻辑,全程无需客户端组件参与。
内容的提问来源于stack exchange,提问作者SeanMarc
相关产品推荐
相关产品推荐

