目前,我正在使用 React 19 将我的 next.js 14 项目升级到 next.js 15,我正面临这个问题,如果您能帮助我,我将很高兴。
这是我的应用程序主页这是电子商务网站
export const revalidate = 0;
import Container from "./components/Container";
import HomeBanner from "./components/HomeBanner";
import NullData from "./components/NullData";
import getProducts, { IProductParams } from "@/actions/getProducts";
import ShuffledProducts from "./components/ShuffledProducts"; // Direct import
interface HomeProps {
searchParams: IProductParams;
}
export default async function Home({ searchParams }: HomeProps) {
const { category, searchTerm } = searchParams;
// Fetch products from the server
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>
{/* Directly render the Client Component */}
<ShuffledProducts products={products} />
</Container>
</div>
);
}
这是我的容器(导入到上面的页面)
interface ContainerProps{
children: React.ReactNode
}
const Container: React.FC<ContainerProps> = ({ children }) => {
return (<div className="
max-w-[1920px]
mx-auto
xl:px-20 md:px-2 px-4">{children}</div>);
};
export default Container;
这是我的 ShuffledProducts
"use client";
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) => (
<ProductCard key={product.id} data={product} />
))}
</div>
);
}
这是我的获取产品
import prisma from "@/libs/prismadb";
export interface IProductParams {
category?: string | null;
searchTerm?: string | null;
}
export default async function getproducts(params: IProductParams) {
try {
const { category, searchTerm } = params;
let searchString = searchTerm;
if (!searchTerm) {
searchString = "";
}
const query: any = {};
if (category) {
query.category = category;
}
const products = await prisma.product.findMany({
where: {
...query,
OR: [
{
name: {
contains: searchString,
mode: "insensitive",
},
description: {
contains: searchString,
mode: "insensitive",
},
},
],
},
include: {
reviews: {
include: {
user: true,
},
orderBy: {
createdDate: "desc",
},
},
},
});
return products;
} catch (error: any) {
console.error("Error fetching products:", error);
throw new Error("Failed to fetch products.");
}
}
我的问题是我收到吹气控制台错误
Console Error
async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
Console Error
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
而且我在终端中也收到此错误
Error: Route "/" used `searchParams.category`. `searchParams` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
at category (src\app\page.tsx:14:10)
12 |
13 | export default async function Home({ searchParams }: HomeProps) {
> 14 | const { category, searchTerm } = searchParams;
| ^
15 |
16 | // Fetch products from the server
17 | const products = await getProducts({ category, searchTerm });
在我的 Next.js 14 版本中,这些错误没有发生,我希望您帮助解决我的 Next.js 15 项目中的这些错误。
Next.js 15 引入了一些重大更改,包括 异步参数
这是来自 docs 的示例,您的页面参数必须如何与新的 Next.js 版本兼容:
// Before (Next.js 14)
type Params = { slug: string }
export default async function Page({params,}: {params: Params}) {
const { slug } = params
}
// After (Next.js 15+)
type Params = Promise<{ slug: string }>
export default async function Page(props: {params: Params}) {
const params = await props.params
const slug = params.slug
}
因此,您的主页代码应类似于以下内容:
export const revalidate = 0;
import Container from "./components/Container";
import HomeBanner from "./components/HomeBanner";
import NullData from "./components/NullData";
import getProducts, { IProductParams } from "@/actions/getProducts";
import ShuffledProducts from "./components/ShuffledProducts"; // Direct import
interface HomeProps {
searchParams: Promise<IProductParams>; // wrapped into Promise<>
}
export default async function Home({ searchParams }: HomeProps) {
const { category, searchTerm } = await searchParams; // await added
// Fetch products from the server
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>
{/* Directly render the Client Component */}
<ShuffledProducts products={products} />
</Container>
</div>
);
}
您也可以从 docs 调用特殊的 cli 命令来自动执行此操作,而不是手动进行此类重构:
npx @next/codemod@canary upgrade latest
Next.js 抱怨的另一个问题
客户端组件尚不支持 async/await
可能是因为您导出服务器功能getproducts而没有使用
'use server'
指令
只需将
'use server'
添加到文件顶部即可:
'use server'; // << ADD THIS
import prisma from "@/libs/prismadb";
export interface IProductParams {
category?: string | null;
searchTerm?: string | null;
}
export default async function getproducts(params: IProductParams) {
try {
const { category, searchTerm } = params;
let searchString = searchTerm;
... other code