首页 > 解决方案 > 如何应用 MathJax/KaTex 来渲染 React 组件

问题描述

我正在使用 React 和 SlateJS 制作一个网络编辑器。编辑器内容中有 LaTex 代码,我希望用户看到渲染的 LaTex 方程。MathJax 和KaTex通过将它们加载为 CDN 具有自动渲染功能。加载后,将呈现 html 正文上的内容。但是当我修改内容时,它们不是实时渲染的。

所以我做了一个按钮,打开一个模式,在一个较小的窗口中呈现不可编辑的编辑内容,我希望在模式中呈现 LaTex 代码。

APP组件:

import {Editor} from 'slate-react';
import ReactModel from 'react-modal';
import RenderedEditorDialog from "./RenderedEditorDialog";

class APP extends React.component {

    ...

    render() {
        return (
            <div className={"editorContainer"}>
                <div className={"editor"}>
                    <Editor
                        autoFocus
                        ref={this.ref}
                        value={this.state.value}
                        onChange={this.onChange}
                        onKeyDown={this.onKeyDown}
                        renderMark={this.renderMarks}
                        renderBlock={this.renderBlock}
                    />
                </div>
                <ReactModal
                    isOpen={this.state.showMathDialog}
                    contentLabel="Rendered content"
                    onRequestClose={this.handleCloseMathDialog}
                >
                    <button onClick={this.handleCloseMathDialog}>Close Dialog</button>
                    <RenderedEditorDialog value={this.state.value}/>
                </ReactModal>
            </div>
        )
    }
}

RenderedEditorDialog(模态)组件:

import {Editor} from 'slate-react';

class RenderedEditorDialog extends React.Component {
    // eslint-disable-next-line no-useless-constructor
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <Editor
                    value={this.props.value}
                    renderMark={this.renderMarks}
                    renderBlock={this.renderBlock}/>
            </div>
        )
    }
}

我的问题是如何应用 MathJax/KaTex 来呈现RenderedEditorDialog组件中的内容?

提前致谢!

标签: reactjsmathjaxreact-componentkatexslatejs

解决方案


KaTeX 可以根据需要应用于单个 DOM 元素,而不是一次全部应用,只需在需要时调用renderMathInElement。调用它componentDidUpdate应该可以解决问题:

import {Editor} from 'slate-react';

class RenderedEditorDialog extends React.Component {
    constructor(props) {
        super(props);
        this.ref = React.createRef();
    }

    render() {
        return (
            <div ref={this.ref}>
                <Editor
                    value={this.props.value}
                    renderMark={this.renderMarks}
                    renderBlock={this.renderBlock}/>
            </div>
        )
    }

    componentDidUpdate() {
        renderMathInElement(this.ref.current, katexOptions);
    }
}

我更喜欢基于钩子的组件而不是类,它看起来像这样:

function RenderedEditorDialog(props) {
    const ref = useRef();
    useEffect(() => {
        renderMathInElement(ref.current, katexOptions);
    });
    return (
        <div ref={ref}>
            <Editor
                value={props.value}
                renderMark={props.renderMarks}
                renderBlock={props.renderBlock}/>
        </div>
    )
};

我不确定你是想要这个RenderedEditorDialog还是另一个更具体的组件,但这应该会给你这个想法。为了速度,您希望应用于renderMathInElement包含更新数学的最小容器。


推荐阅读