React-toastify 通用通知工具函数中HTML内容无法正常渲染的问题求助
我完全理解你遇到的困扰——想在通用工具函数里让React-toastify渲染带HTML结构的通知,但dangerouslySetInnerHTML没法直接在toast方法里生效,因为你之前的用法没踩对React-toastify的API规则。咱们来快速解决这个问题:
问题核心
你之前把HTML拼接成字符串,还尝试传dangerouslySetInnerHTML属性对象给toast.success(),但toast系列方法(比如toast.success、toast.error)其实支持直接传入**React元素(JSX)**作为内容,而不是字符串或DOM属性配置,这才是正确的打开方式。
修正后的完整实现
我们直接在工具函数里构建JSX元素,再传给对应的toast方法,就能正常渲染HTML结构了,甚至不需要依赖dangerouslySetInnerHTML(如果内容是可信的,这种方式更安全)。
1. 改造src/utils/Common.ts工具函数
import { toast } from 'react-toastify'; import React from 'react'; // 必须引入React才能在工具函数里写JSX export function showToaster({ type = '', title, description }) { // 直接构建React元素,替代原来的HTML字符串拼接 const toasterContent = ( <div> <h5>{title}</h5> <div>{description}</div> </div> ); switch(type){ case 'success': return toast.success(toasterContent); case 'fail': return toast.error(toasterContent); case 'warn': return toast.warn(toasterContent); default: return toast(toasterContent, { style:{ background: '#fff2df'}}); } }
2. 如果description本身带HTML标签(比如<br>、<span>)
如果你的description是包含HTML标签的字符串(比如"这是一段<br>带换行的描述"),那可以在JSX里用dangerouslySetInnerHTML解析,注意只在内容完全可信时这么做:
const toasterContent = ( <div> <h5>{title}</h5> <div dangerouslySetInnerHTML={{ __html: description }} /> </div> );
⚠️ 安全提示:如果内容来自用户输入,一定要用DOMPurify这类库净化后再传入,避免XSS攻击风险。
3. 保持组件代码不变
你的index.tsx里的按钮和ToastContainer逻辑完全不需要修改,继续保留原来的写法即可:
// index.tsx import { ToastContainer, Slide } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; // 别忘了引入默认样式! import { showToaster } from './utils/Common'; const notify = () => { const notifyMsg = { type: 'success', title:"Toaster banner title", description:"Description This is the description part you can add your content here." }; showToaster(notifyMsg); } const Index = () => { return ( <> <button onClick={notify}>test</button> <ToastContainer transition={Slide} autoClose={false} position="bottom-right" style={{ height: "100px", width: "500px" }} /> </> ) } export default Index;
为什么这样可行?
React-toastify的toast.success()等方法,参数类型是React.ReactNode——也就是任何React能渲染的内容:字符串、数字、JSX元素都可以。直接传JSX元素的话,React会正常解析渲染里面的结构,自然就能显示你想要的<h5>和<div>排版了。
额外提醒
- 一定要引入
react-toastify的CSS文件,不然通知的基础样式会错乱; - 如果你的
title或description包含用户输入的内容,务必先做XSS过滤,避免安全漏洞。
这样修改后,点击按钮就能看到带正确HTML结构的通知啦~
备注:内容来源于stack exchange,提问作者Prasad Patel

