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

Next.js静态构建时useEffect未执行,KaTeX组件无法渲染求解决

解决Next.js App Router静态站点中KaTeX组件不渲染的问题

问题根源在于静态站点生成(SSG)阶段,'use client'组件的useEffect仅会在客户端hydrate时执行,服务端渲染过程中不会运行,因此生成的静态HTML仅包含空的<span>标签,导致公式无法显示。以下是两种可行的解决方案:

方案1:使用KaTeX服务端渲染预生成HTML(推荐)

利用KaTeX的renderToString方法直接生成公式对应的HTML字符串,通过dangerouslySetInnerHTML插入到组件中。这种方式能让静态生成过程直接输出公式的完整HTML,无需依赖客户端useEffect,首次加载即可显示公式。

修改后的组件代码:

'use client'
import katex from 'katex'
import 'katex/dist/katex.min.css'

export default function TeX({ equation, display }: { equation: string, display: boolean }) {
  const formulaHtml = katex.renderToString(equation, {
    displayMode: display,
    throwOnError: false // 可选,避免公式语法错误导致组件崩溃
  })

  return (
    <span dangerouslySetInnerHTML={{ __html: formulaHtml }} />
  )
}

方案2:确保客户端hydrate时触发渲染(兼容动态公式)

如果公式需要动态更新,保留useEffect的同时,通过状态标识客户端环境,确保渲染逻辑仅在客户端执行。静态生成时可添加占位文本,避免空标签显示。

修改后的组件代码:

'use client'
import { useEffect, useRef, useState } from 'react'
import katex from 'katex'
import 'katex/dist/katex.min.css'

export default function TeX({ equation, display }: { equation: string, display: boolean }) {
    const ref = useRef<HTMLSpanElement>(null);
    const [isClient, setIsClient] = useState(false);

    useEffect(() => {
        // 标记已进入客户端环境
        setIsClient(true);
    }, []);

    useEffect(() => {
        if (isClient && ref.current) {
            katex.render(equation, ref.current, {
                displayMode: display,
                throwOnError: false
            });
        }
    }, [equation, isClient, display]);

    return (
        <span ref={ref}>{!isClient ? '加载中...' : ''}</span>
    )
}

注意事项

  • 确保正确引入KaTeX的CSS文件,否则公式样式会异常
  • 设置throwOnError: false可以避免因公式语法错误导致组件渲染失败
  • 方案1的性能更优,静态HTML直接包含公式内容,适合大多数静态站点场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:52:14