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

Next.js 15升级报错:use client与searchParams使用问题排查

Next.js 15(React 19)升级后首页错误修复方案

一、修复终端错误:路由/需先await searchParams再使用属性

Next.js 15对App Router的服务器组件参数做了调整,searchParams现在是异步Promise类型,必须先解析后才能访问其属性。

修改首页Home组件代码:

  1. 更新Props类型,将searchParams改为Promise类型:
interface HomeProps {
  searchParams: Promise<IProductParams>;
}
  1. 在组件内先await解析searchParams,再解构属性:
export default async function Home({ searchParams }: HomeProps) {
  // 先解析异步的searchParams
  const resolvedParams = await searchParams;
  const { category, searchTerm } = resolvedParams;

  // 后续逻辑保持不变
  const products = await getProducts({ category, searchTerm });

  if (products.length === 0) {
    return <NullData title="OOPS ! No Products Found" />;
  }

  return (
    <div className="p-8">
      <Container>
        <div className="pb-8">
          <HomeBanner />
        </div>
        <ShuffledProducts products={products} />
      </Container>
    </div>
  );
}

二、修复控制台错误:客户端组件async/await不支持、未缓存Promise挂起

排查与修复步骤:

  1. 检查服务端模块是否误加'use client'
    确认getProducts、Container、HomeBanner等被服务器组件Home导入的模块,都没有添加'use client'指令(当前提供的代码中无此问题,若后续新增模块需注意)。

  2. 处理客户端组件内的异步操作
    控制台提示的“未缓存Promise挂起”,大概率是因为ShuffledProducts导入的ProductCard组件内部存在未被Suspense包裹的异步逻辑。修复方式如下:
    在ShuffledProducts组件中,用React 19的Suspense包裹ProductCard,为异步操作提供加载状态:

"use client";
import { Suspense } from 'react';
import ProductCard from "./products/ProductCard";

interface ShuffledProductsProps {
  products: any[];
}

export default function ShuffledProducts({ products }: ShuffledProductsProps) {
  function shuffleArray(array: any[]) {
    for (let i = array.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
  }

  const shuffledProducts = shuffleArray(products);

  return (
    <div
      className="grid 
      grid-cols-2
      sm:grid-cols-3 
      lg:grid-cols-6
      xl:grid-col-5 
      2xl:grid-col-6 
      gap-8"
    >
      {shuffledProducts.map((product: any) => (
        <Suspense key={product.id} fallback={<div className="animate-pulse bg-gray-200 rounded-lg h-full"></div>}>
          <ProductCard data={product} />
        </Suspense>
      ))}
    </div>
  );
}

注意:如果ProductCard组件内直接使用了async/await定义组件(如async function ProductCard()),需改为同步组件,异步逻辑移到useEffect或用React的cache函数缓存Promise。

  1. 修正函数名大小写不一致问题
    getProducts文件中导出的函数名为getproducts(小写p),但首页导入的是getProducts(大写P),虽然当前代码能运行,但属于潜在问题,建议统一函数名:
// getProducts.ts文件中修改函数名
export default async function getProducts(params: IProductParams) {
  // 原逻辑保持不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:49:59