如何在React服务器组件中显示Toast?

问题描述 投票:0回答:1

我正在将 Next.js 14 与应用程序路由器一起使用。

我有两个服务器组件:

  1. 列表页面
    /products
    显示多个产品
  2. 产品详情页面
    /products/{id}

/products/{id}
上,我通过服务器操作检查
id
在我的产品数据库中是否可用,然后渲染产品。

如果产品不可用,我想将用户重定向回

/products
并显示一条提示消息,表明未找到产品。

重定向非常简单:

import { redirect } from 'next/navigation'

async function getNoProduct() {
  return null
}

export default async function RedirectFromPage() {
  
  let res = await getNoProduct()
  if (!res === null) {
    redirect('/products')
  }
  return (
    <div>
      <p>Hello SO</p>
    </div>
  )
}

但是,我在实现 toast 消息时遇到了困难(通过 shadcn 使用 sonner toast)。

像下面这样直接添加toast是不行的,因为

/products/{id}
是一个服务器组件,而toast依赖于useEffect, 例如

import { redirect } from 'next/navigation'
import { useToast } from '@/components/ui/use-toast'

async function getNoProduct() {
  return null
}

export default async function RedirectFromPage() {
  const { toast } = useToast()

  let res = await getNoProduct()
  if (!res === null) {
    // Show toast
    toast({
      title: 'Error',
      description: 'Product not found',
    })
    redirect('/products')
  }
  return (
    <div>
      <p>Hello SO</p>
    </div>
  )
}

会导致错误

Error: useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component

基于与服务器操作相关的另一个SO问题(here),我认为我可以使用cookie将错误传达给

/products
,然后渲染使用toast的客户端组件,但遇到问题,因为我可以触发这些服务器仅来自客户端组件的操作

我应该如何处理这个问题? toast 是这里的组件类型错误还是有更好的方法来做到这一点?

next.js toast react-server-components
1个回答
0
投票

我的理解是 toast 包是为客户端设计的。对于服务器端,我认为您可以创建一个 loading.tsx 页面,nextjs 将显示加载页面,然后显示预期页面。如果它是服务器渲染页面内的客户端组件,您应该能够使用 React Suspense 将客户端组件包装在服务器渲染页面中

© www.soinside.com 2019 - 2024. All rights reserved.