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
相关产品推荐
相关产品推荐

