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

Sonner Toast在客户端组件挂载时无法渲染的问题求助

解决Next.js中Sonner Toast组件挂载时不显示的问题

问题描述

在Next.js App Router项目中使用Sonner库实现Toast功能:

  • 按钮点击触发toast.info()可正常显示Toast
  • 客户端组件挂载时通过useEffect(() => {}, [])调用toast.success()无法渲染Toast

问题原因

在Next.js App Router的渲染流程中,MyComponent的useEffect可能在布局中的ToasterComp完成初始化前就执行了,导致toast调用未被Toaster实例捕获。

解决方案

方法1:延迟Toast调用到下一个渲染周期

通过setTimeout将toast调用延迟到下一个事件循环,确保Toaster已完成挂载:

"use client"

import { useEffect } from "react"
import { toast } from "sonner"

const MyComponent = () => {
  useEffect(() => {
    setTimeout(() => {
      toast.success("This is the toast that will be shown.")
    }, 0)
  }, [])

  return (
    <div>
      <button
        className="bg-blue-500 text-stone-50 border-2 border-slate-900 py-2 px-4 rounded-lg mt-4"
        onClick={() => toast.info('You clicked the button.')}
      >
        Show toast
      </button>
    </div>
  )
}

export default MyComponent

方法2:调整Toaster在组件树中的渲染顺序

将ToasterComp放在children之前,确保它优先完成初始化:

<!-- app/layout.tsx -->
<html lang="en">
  <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
    <ToasterComp />
    {children}
  </body>
</html>

方法3:使用useLayoutEffect替代useEffect

useLayoutEffect会在DOM更新完成后同步执行,确保Toaster已渲染完成:

"use client"

import { useLayoutEffect } from "react"
import { toast } from "sonner"

const MyComponent = () => {
  useLayoutEffect(() => {
    toast.success("This is the toast that will be shown.")
  }, [])

  return (
    <div>
      <button
        className="bg-blue-500 text-stone-50 border-2 border-slate-900 py-2 px-4 rounded-lg mt-4"
        onClick={() => toast.info('You clicked the button.')}
      >
        Show toast
      </button>
    </div>
  )
}

export default MyComponent

验证说明

以上方法均可确保Toaster实例在toast调用前完成初始化,从而正确显示挂载时的Toast。优先推荐方法1或方法2,侵入性更低且适配性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:43:29