在 React Native 中基于 MathJax 实现文字与数学公式混排
#移动端开发React Native(RN)本身没有内置的LaTeX渲染能力,而MathJax作为成熟的公式渲染库,是解决这个问题的最佳选择之一。
着急的话可以直接去看 组件完整代码
在普通网页中用MathJax渲染LaTeX公式
在RN中集成前,我们先从最基础的网页场景入手,理解 MathJax 的核心用法,因为RN中我们本质上是通过 WebView 来运行 MathJax。
核心实现思路
- 引入 MathJax 的 js 文件
- 配置 MathJax 的渲染规则(如行内公式的分隔符)
- 在HTML中写入 LaTeX 公式内容
基础代码示例
重点说明
tex-svg.js是 MathJax 的 SVG 渲染版本,也可以选择tex-mml-chtml.js( HTML 渲染):- HTML 模式:依赖外部 WebFonts 字体文件。在 React Native 中通过
file:///android_asset/加载时,浏览器可能因为安全策略拦截字体请求,导致公式显示为 fallback 字体。 - SVG 模式:将公式直接转换为内联的
<path>路径。它不依赖任何外部字体文件,只要 JS 加载成功,公式就能完美显示,完全不存在“字体显示不出”的兼容性问题。
- HTML 模式:依赖外部 WebFonts 字体文件。在 React Native 中通过
inlineMath配置决定了哪些符号包裹的内容会被识别为行内公式,可以根据需要自定义分隔符,如$公式$或\(公式\);
在 RN 中配置 MathJax 本地文件
为了方便打包后离线场景可用,我们不能直接使用 CDN 获取 js 文件,因此需要将 MathJax 文件放到项目本地,分 iOS 和 Android 两个平台配置。
步骤1:下载MathJax文件
从 jsdelivr 下载 tex-svg.js 文件。
步骤2:分平台放置文件
Android 配置
- 将
tex-svg.js复制到@/android/app/src/main/assets/mathjax下。
iOS 配置(来自 AI ,没有测试,可能有误)
- 将 MathJax 的
es5目录拖入 Xcode 的项目工程中(建议放到Resources目录); - 勾选「Copy items if needed」和对应的 Target,确保文件被打包进 App;
- iOS中访问本地文件的路径为相对路径(无需
file://前缀)。
步骤3:RN中获取平台对应的MathJax路径
|
|
在 RN 中封装组件:核心逻辑实现
基于 react-native-webview 和 MathJax,我们封装一个可复用的 TextWithLatex 组件,核心解决两个问题:公式渲染、高度自适应(避免WebView高度固定导致内容截断/留白)。
组件基础结构与Props定义
先定义组件的入参,为了让 WebView 中的公式看起来更像是原生组件,我决定让它支持自定义文本颜色、背景色、字体大小等:
|
|
高度自适应
WebView 的高度默认固定,公式渲染后高度可能变化,因此需要:
- 用
useState维护 WebView 的动态高度; - 在 MathJax 渲染完成后,计算 HTML 内容的实际高度,通过
postMessage传递给RN; - RN 接收高度后更新 WebView 容器高度。
|
|
组件返回结构
最终返回包含WebView的容器,绑定动态高度和事件:
|
|
组件使用示例
封装完成后,使用方式非常简单,只需传入包含LaTeX公式的content即可:
|
|
完整组件代码
以下是TextWithLatex.tsx的完整代码,可直接复制使用(需确保已安装react-native-webview):
|
|
性能优化
MathJax渲染有一定耗时,建议通过正则表达式判断是否真的有公式 再用 WebView 渲染,避免无意义的渲染;
|
|