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

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>
  );
}

额外提示:

  1. 你提供的代码存在两处问题:重复声明venues变量、data未定义,建议修正后再使用。
  2. 若需要动态过滤(比如基于用户筛选条件),可以读取服务器组件的searchParams参数,根据参数执行对应过滤逻辑,全程无需客户端组件参与。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:52:17