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

Next.js中基于URL查询参数过滤Server Component(Prisma)问题

问题解决步骤

1. 确保Page组件正确获取SearchParams

根据你的page.tsx是服务器组件还是客户端组件,选择对应实现方式:

服务器组件(推荐,适配Prisma查询场景)

在src/app/page.tsx中,将searchParams作为组件props接收:

export default async function Home({
  searchParams,
}: {
  searchParams?: { [key: string]: string | string[] | undefined };
}) {
  // 处理参数,兼容可能的数组情况(URL中重复key时)
  const category = Array.isArray(searchParams?.category) 
    ? searchParams.category[0] 
    : searchParams?.category;
  
  // 传入分类参数获取列表数据
  const listings = await getListings(category);

  return (
    <div>
      {/* 导航栏等页面结构 */}
      <div className="listings-grid">
        {listings.map(listing => (
          {/* 渲染单个房源卡片 */}
        ))}
      </div>
    </div>
  );
}

客户端组件(若page标记了'use client')

使用Next.js的useSearchParams钩子获取参数:

'use client';

import { useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import getListings from '@/app/actions/getListings';

export default function Home() {
  const searchParams = useSearchParams();
  const [listings, setListings] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const category = searchParams.get('category');
      const data = await getListings(category || undefined);
      setListings(data);
    };
    fetchData();
  }, [searchParams]);

  return (
    {/* 页面渲染内容 */}
  );
}

2. 完善getListings的过滤逻辑

在src/app/actions/getListings.ts中,确保正确接收分类参数并添加Prisma过滤条件:

import prisma from '@/lib/prisma';

export async function getListings(category?: string) {
  try {
    return await prisma.listing.findMany({
      where: {
        // 仅当分类参数存在时,添加过滤规则
        ...(category && { category }),
      },
      // 可选:添加排序、关联查询等配置
      orderBy: { createdAt: 'desc' },
    });
  } catch (error) {
    console.error('获取列表失败:', error);
    throw new Error('Failed to fetch listings');
  }
}

3. 检查CategoryBox的跳转逻辑

确保src/app/components/CategoryBox.tsx使用Next.js的Link组件正确传递查询参数:

import Link from 'next/link';
import { IconType } from 'react-icons';

interface CategoryBoxProps {
  label: string;
  icon: IconType;
  category: string;
  isActive?: boolean;
}

export default function CategoryBox({ 
  label, 
  icon: Icon, 
  category, 
  isActive 
}: CategoryBoxProps) {
  return (
    <Link
      href={{
        pathname: '/',
        query: { category },
      }}
      className={`category-box ${isActive ? 'active' : ''}`}
    >
      <Icon size={24} />
      <span>{label}</span>
    </Link>
  );
}

4. 禁用页面缓存(若遇到缓存问题)

如果Next.js缓存导致参数变化后页面不重新渲染,在page.tsx顶部添加动态配置:

export const dynamic = 'force-dynamic';

export default async function Home({ searchParams }) {
  // 页面逻辑
}

额外排查点

  • 确认Prisma模型中存在category字段,且字段类型与传递的参数匹配(如字符串类型)。
  • 查看浏览器控制台,检查是否有Prisma查询错误或数据请求失败的报错信息。
  • 若URL中存在多个相同key的参数,需处理数组类型的参数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:52:39