在 React 组件中渲染数学
Rendering Math in React Component
我正在尝试使用 MathJax 在 React 组件中呈现数学方程式。如果我在 HTML 文件中预渲染它实际上效果很好,但是当我尝试在 React 中渲染它时它是一团糟。
这是我的代码
class Latex extends React.Component {
constructor(props) {
super(props);
}
componentDidMount(){
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);
}
componentDidUpdate() {
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);
}
render() {
//dangerouslySetInnerHTML={{__html: this.props.children}}
return (
<h5 dangerouslySetInnerHTML={{__html: this.props.children}}></h5>
);
}
}
Math Display both in Regular HTML and React Element
你的逻辑很好,但这不是反应的工作方式。为什么不使用 react-mathjax or react-formula-beautifier 而不是使用 MathJax。并像使用另一个组件一样使用它们(这就是 React 的工作方式)。
Here你有官方例子
建议:如果你想在react中使用一些lib,尝试搜索react-nameoflib。大多数图书馆都有他的反应版本。
哦不,当我发现自己做错了什么时,我对自己感到非常失望。我将 Block 的显示应用于呈现 Latex 的 Span 元素(我的看法是它将整个块视为一个块)并将每个 Equation 字符放在单独的行上。将显示更改为 "inline" 解决了问题。
我使用了 algebra.js and react-mathjax libraries to get it working in ES6. Because all these other packages are poorly maintained. For react-mathjax please use this repo.
的组合
下面是一个显示分数的例子:
import React from 'react';
import { Fraction, toTex } from 'algebra.js';
import { Node, Context } from 'react-mathjax';
function Formula(props) {
return (
<Context input="tex">
<Node inline>{props.tex}</Node>
</Context>
);
}
export default function FractionDisplay() {
const a = new Fraction(1, 5);
const b = new Fraction(2, 7);
const answer = a.multiply(b);
const question = <Formula tex={`${toTex(a)} × ${toTex(b)} = ${toTex(answer)}`} />;
return (
<div>
{question}
</div>
);
}
在组件 class declare var MathJax;
之前添加此内容。它应该可以无缝运行。
已经有几年了,但是如果有人正在寻找基于函数式 + mathjax3 的方法,那么这里有这个 repo:
https://github.com/jpribyl/react-hook-mathjax
可在 https://johnpribyl.com/react-hook-mathjax/
获得它的演示
用法是这样的:
基本内联显示
import React from "react";
import Tex2SVG from "react-hook-mathjax";
function App() {
return (
<div className="App">
<header className="App-header">
<Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
</header>
</div>
);
}
export default App;
自定义 MathJax 选项
import React from "react";
import Tex2SVG, { MathJaxProvider } from "react-hook-mathjax";
// This object contains the default options, more info at:
// http://docs.mathjax.org/en/latest/options/output/svg.html
const mathJaxOptions = {
svg: {
scale: 1, // global scaling factor for all expressions
minScale: .5, // smallest scaling factor to use
mtextInheritFont: false, // true to make mtext elements use surrounding font
merrorInheritFont: true, // true to make merror text use surrounding font
mathmlSpacing: false, // true for MathML spacing rules, false for TeX rules
skipAttributes: {}, // RFDa and other attributes NOT to copy to the output
exFactor: .5, // default size of ex in em units
displayAlign: 'center', // default for indentalign when set to 'auto'
displayIndent: '0', // default for indentshift when set to 'auto'
fontCache: 'local', // or 'global' or 'none'
localID: null, // ID to use for local font cache (for single equation processing)
internalSpeechTitles: true, // insert <title> tags with speech content
titleID: 0 // initial id number to use for aria-labeledby titles
}
}
function App() {
return (
<div>
<MathJaxProvider options={mathJaxOptions} />
<div className="App">
<header className="App-header">
<Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
</header>
</div>
</div>
);
}
export default App;
正在解析用户输入
import React from "react";
import Tex2SVG from "react-hook-mathjax";
function App() {
const [inputValue, setInputValue] = React.useState(
"G_{\mu\nu} + \Lambda g_{\mu\nu} = \kappa T_{\mu\nu}",
);
return (
<div className="App">
<header className="App-header">
<h3>React Hook MathJax</h3>
<input
type="text"
defaultValue={inputValue}
onChange={e => setInputValue(e.target.value)}
/>
<div className="tex-container">
<Tex2SVG class="tex" tabindex={-1} latex={inputValue} />
</div>
</header>
</div>
);
}
export default App;
处理错误状态
import React from "react";
import Tex2SVG from "react-hook-mathjax";
const getErrorFromHTML = (html) =>
html.children[1].firstChild.firstChild.attributes["data-mjx-error"].value;
function App() {
const [inputValue, setInputValue] = React.useState(
"G_{\mu\nu} + \Lambda g_{\mu\nu} = \kappa T_{\mu\nu}",
);
const [lastValidInput, setLastValidInput] = React.useState("");
const [error, setError] = React.useState(null);
const hasError = error !== null;
return (
<div className="App">
<header className="App-header">
<h3>React Hook MathJax</h3>
<input
className={`${hasError ? "error" : ""}`}
type="text"
defaultValue={inputValue}
onChange={e => {
setInputValue(e.target.value);
setError(null);
}}
/>
<div className="tex-container">
<Tex2SVG
class="tex"
tabindex={-1}
latex={hasError ? lastValidInput : inputValue}
onSuccess={() =>
setLastValidInput(hasError ? lastValidInput : inputValue)
}
onError={html => setError(getErrorFromHTML(html))}
/>
</div>
{hasError && <div>hint: {error}</div>}
</header>
</div>
);
}
export default App;
API
MathJaxProvider
道具:
options
对象,可选
- 设置MathJax configuration。
- 默认:MathJax 官方配置
Tex2SVG
道具:
latex
字符串,必需
- 传递给 MathJax 进行转换的字符串。必须有效  才能成功转换为
svg
- 默认:
''
onSuccess
(HTMLElement) => 无效,可选
- 在将 LaTeX 字符串成功转换为
svg
后触发 - 它接收由 MathJax 生成的 html 对象
- 默认:
(html: HTMLElement) => {}
onError
(HTMLElement) => 无效,可选
- 在将 LaTeX 字符串转换为
svg
失败后触发 - 它接收由 MathJax 生成的 html 对象
- 默认:
(html: HTMLElement) => {}
Other html attributes
{[key: string]: any} 可选
- 传递给该组件的所有其他道具将直接转换到 DOM 节点
- 这允许您添加 css 类 或其他处理程序,请参阅上面的用法示例
- 注意:这不会附加到虚拟 DOM,因此传递
class
- 而不是 className
等
我正在尝试使用 MathJax 在 React 组件中呈现数学方程式。如果我在 HTML 文件中预渲染它实际上效果很好,但是当我尝试在 React 中渲染它时它是一团糟。
这是我的代码
class Latex extends React.Component {
constructor(props) {
super(props);
}
componentDidMount(){
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);
}
componentDidUpdate() {
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);
}
render() {
//dangerouslySetInnerHTML={{__html: this.props.children}}
return (
<h5 dangerouslySetInnerHTML={{__html: this.props.children}}></h5>
);
}
}
Math Display both in Regular HTML and React Element
你的逻辑很好,但这不是反应的工作方式。为什么不使用 react-mathjax or react-formula-beautifier 而不是使用 MathJax。并像使用另一个组件一样使用它们(这就是 React 的工作方式)。
Here你有官方例子
建议:如果你想在react中使用一些lib,尝试搜索react-nameoflib。大多数图书馆都有他的反应版本。
哦不,当我发现自己做错了什么时,我对自己感到非常失望。我将 Block 的显示应用于呈现 Latex 的 Span 元素(我的看法是它将整个块视为一个块)并将每个 Equation 字符放在单独的行上。将显示更改为 "inline" 解决了问题。
我使用了 algebra.js and react-mathjax libraries to get it working in ES6. Because all these other packages are poorly maintained. For react-mathjax please use this repo.
的组合下面是一个显示分数的例子:
import React from 'react';
import { Fraction, toTex } from 'algebra.js';
import { Node, Context } from 'react-mathjax';
function Formula(props) {
return (
<Context input="tex">
<Node inline>{props.tex}</Node>
</Context>
);
}
export default function FractionDisplay() {
const a = new Fraction(1, 5);
const b = new Fraction(2, 7);
const answer = a.multiply(b);
const question = <Formula tex={`${toTex(a)} × ${toTex(b)} = ${toTex(answer)}`} />;
return (
<div>
{question}
</div>
);
}
在组件 class declare var MathJax;
之前添加此内容。它应该可以无缝运行。
已经有几年了,但是如果有人正在寻找基于函数式 + mathjax3 的方法,那么这里有这个 repo:
https://github.com/jpribyl/react-hook-mathjax
可在 https://johnpribyl.com/react-hook-mathjax/
获得它的演示用法是这样的:
基本内联显示
import React from "react";
import Tex2SVG from "react-hook-mathjax";
function App() {
return (
<div className="App">
<header className="App-header">
<Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
</header>
</div>
);
}
export default App;
自定义 MathJax 选项
import React from "react";
import Tex2SVG, { MathJaxProvider } from "react-hook-mathjax";
// This object contains the default options, more info at:
// http://docs.mathjax.org/en/latest/options/output/svg.html
const mathJaxOptions = {
svg: {
scale: 1, // global scaling factor for all expressions
minScale: .5, // smallest scaling factor to use
mtextInheritFont: false, // true to make mtext elements use surrounding font
merrorInheritFont: true, // true to make merror text use surrounding font
mathmlSpacing: false, // true for MathML spacing rules, false for TeX rules
skipAttributes: {}, // RFDa and other attributes NOT to copy to the output
exFactor: .5, // default size of ex in em units
displayAlign: 'center', // default for indentalign when set to 'auto'
displayIndent: '0', // default for indentshift when set to 'auto'
fontCache: 'local', // or 'global' or 'none'
localID: null, // ID to use for local font cache (for single equation processing)
internalSpeechTitles: true, // insert <title> tags with speech content
titleID: 0 // initial id number to use for aria-labeledby titles
}
}
function App() {
return (
<div>
<MathJaxProvider options={mathJaxOptions} />
<div className="App">
<header className="App-header">
<Tex2SVG display="inline" latex="e^{i \pi} + 1 = 0" />
</header>
</div>
</div>
);
}
export default App;
正在解析用户输入
import React from "react";
import Tex2SVG from "react-hook-mathjax";
function App() {
const [inputValue, setInputValue] = React.useState(
"G_{\mu\nu} + \Lambda g_{\mu\nu} = \kappa T_{\mu\nu}",
);
return (
<div className="App">
<header className="App-header">
<h3>React Hook MathJax</h3>
<input
type="text"
defaultValue={inputValue}
onChange={e => setInputValue(e.target.value)}
/>
<div className="tex-container">
<Tex2SVG class="tex" tabindex={-1} latex={inputValue} />
</div>
</header>
</div>
);
}
export default App;
处理错误状态
import React from "react";
import Tex2SVG from "react-hook-mathjax";
const getErrorFromHTML = (html) =>
html.children[1].firstChild.firstChild.attributes["data-mjx-error"].value;
function App() {
const [inputValue, setInputValue] = React.useState(
"G_{\mu\nu} + \Lambda g_{\mu\nu} = \kappa T_{\mu\nu}",
);
const [lastValidInput, setLastValidInput] = React.useState("");
const [error, setError] = React.useState(null);
const hasError = error !== null;
return (
<div className="App">
<header className="App-header">
<h3>React Hook MathJax</h3>
<input
className={`${hasError ? "error" : ""}`}
type="text"
defaultValue={inputValue}
onChange={e => {
setInputValue(e.target.value);
setError(null);
}}
/>
<div className="tex-container">
<Tex2SVG
class="tex"
tabindex={-1}
latex={hasError ? lastValidInput : inputValue}
onSuccess={() =>
setLastValidInput(hasError ? lastValidInput : inputValue)
}
onError={html => setError(getErrorFromHTML(html))}
/>
</div>
{hasError && <div>hint: {error}</div>}
</header>
</div>
);
}
export default App;
API
MathJaxProvider
道具:
options
对象,可选
- 设置MathJax configuration。
- 默认:MathJax 官方配置
Tex2SVG
道具:
latex
字符串,必需
- 传递给 MathJax 进行转换的字符串。必须有效  才能成功转换为
svg
- 默认:
''
onSuccess
(HTMLElement) => 无效,可选
- 在将 LaTeX 字符串成功转换为
svg
后触发 - 它接收由 MathJax 生成的 html 对象
- 默认:
(html: HTMLElement) => {}
onError
(HTMLElement) => 无效,可选
- 在将 LaTeX 字符串转换为
svg
失败后触发 - 它接收由 MathJax 生成的 html 对象
- 默认:
(html: HTMLElement) => {}
Other html attributes
{[key: string]: any} 可选
- 传递给该组件的所有其他道具将直接转换到 DOM 节点
- 这允许您添加 css 类 或其他处理程序,请参阅上面的用法示例
- 注意:这不会附加到虚拟 DOM,因此传递
class
- 而不是className
等