在 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 对象,可选

Tex2SVG道具:

latex 字符串,必需

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