作为新手,实在没想到错误多多,一个统计代码居然折腾了几个小时才解决。这是最后的报错:React 错误 #418 通常与 dangerouslySetInnerHTML
中包含的文本内容有关。当在包含 <script>
标签的 HTML 字符串中使用 dangerouslySetInnerHTML
时,React 可能会遇到问题。
立即修复:使用客户端组件避免 React 错误
// components/AnalyticsInjector.tsx
'use client'
import { useEffect } from 'react'
interface AnalyticsInjectorProps {
trackingCode: string
}
export default function AnalyticsInjector({ trackingCode }: AnalyticsInjectorProps) {
useEffect(() => {
if (!trackingCode) return
const container = document.createElement('div')
container.innerHTML = trackingCode
const scripts = container.querySelectorAll('script')
scripts.forEach(originalScript => {
const newScript = document.createElement('script')
Array.from(originalScript.attributes).forEach(attr => {
newScript.setAttribute(attr.name, attr.value)
})
if (originalScript.src) {
newScript.src = originalScript.src
} else if (originalScript.textContent) {
newScript.textContent = originalScript.textContent
}
document.body.appendChild(newScript)
})
}, [trackingCode])
return null
}
然后在 layout.tsx 中:
import AnalyticsInjector from '@/components/AnalyticsInjector'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh-CN">
<head>
{/* head 内容 */}
</head>
<body>
{children}
{settings.analytics.trackingCode && (
<AnalyticsInjector trackingCode={settings.analytics.trackingCode} />
)}
</body>
</html>
)
}
为什么会出现 React 错误 #418:
React 在处理包含脚本标签的
dangerouslySetInnerHTML
时可能遇到问题服务端渲染和客户端水合不匹配
脚本标签的特殊处理机制与 React 的虚拟 DOM 冲突
这个方案的优势:
完全避免了
dangerouslySetInnerHTML
的问题脚本会正确执行
支持各种类型的统计代码
客户端渲染,避免 SSR 问题