React プロジェクトを作成する際、数学の式をウェブページ上にレンダリングしたいが、他の React コンポーネントを使用したくない場合、動的なロードを使用して DOM を直接レンダリングします。
Mathjax@3 は大幅に更新され、使用方法も 2.x バージョンと異なります。
React での動的な js のロード#
まず、動的に js をロードする方法を知る必要があります。js を新しいスクリプトノードにマウントして、DOM に追加するだけです。
script
要素を作成し、src
属性にロードするリンクを設定し、ノードを body 要素に追加します。
以下のように関数をラップするだけで、ロードする js のリンクを渡すだけで、.then
メソッドを使用して後続の操作を行うことができます。
export const loadJS = (url: string) =>
new Promise(function (resolve, reject) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.body.appendChild(script);
script.onload = function () {
resolve(`success: ${url}`);
};
script.onerror = function () {
reject(Error(`${url} load error!`));
};
});
使用する場所:
loadJS(url)
.then(() => {
// 何かを実行
})
.catch(() => {
// 何かを実行
});
[email protected]バージョン#
まず、参考になる公式リンクを示します。この記事ではわかりにくいかもしれません。
- MathJax の読み込みと設定
https://docs.mathjax.org/en/v2.7-latest/configuration.html - MathJax の動的な読み込み
https://docs.mathjax.org/en/v2.7-latest/advanced/dynamic.html - ページ上の数式の変更
https://docs.mathjax.org/en/v2.7-latest/advanced/typeset.html
Mathjax をロードした後、適切なタイミングで mathjax が DOM をレンダリングするだけです。
例を挙げます:
componentDidMount() {
const mathjaxUrl = 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-AMS_CHTML';
loadJS(mathjaxUrl).then(() => {
this.showMathjax();
});
}
componentDidUpdate () {
if (!(window as any).MathJax) {
(window as any).MathJax.Hub.Queue(['Typeset', (window as any).MathJax.Hub, ReactDOM.findDOMNode(this)]);
}
}
showMathjax = () => {
if ((window as any).MathJax) {
(window as any).MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']],
skipTags: ['script', 'noscript', 'style', 'textarea', 'code', 'a'],
},
CommonHTML: {
scale: 120,
linebreaks: { automatic: true },
},
'HTML-CSS': { linebreaks: { automatic: true } },
SVG: { linebreaks: { automatic: true } },
TeX: { noErrors: { disabled: true } },
});
} else {
setTimeout(this.showMathjax, 1000);
}
};
2.x のバージョンでは、Mathjax.Hub.Config
を使用して設定する必要があります。これらの設定は理解しやすく、tex2jax
では数学の式をどのようにレンダリングするかを設定しています。
インラインの数式は$...$
で囲み、複数行の数式は$$...$$
で囲みます。どのタグ内のものはレンダリングしないように設定しています。
次に、いくつかのモードでのレンダリングの表示方法を設定します。上記でロードした js の後ろに?config=TeX-AMS_CHTML
があることから、ロードしたのは CHTML の設定であり、さまざまな設定によって表示が異なります。参照:https://docs.mathjax.org/en/v2.7-latest/config-files.html
Mathjax
がロードされると、ページがレンダリングされますが、シングルページアプリケーションでは、Mathjax
はページの DOM が更新されるたびに再レンダリングされません。MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);
を使用して、Mathjax
に DOM を手動でレンダリングさせる必要があります。componentDidUpdate
に追加してください。
mathjax@3 バージョン#
同様に公式ドキュメントのリンクを提供します:
- MathJax の設定
http://docs.mathjax.org/en/v3.0-latest/options/index.html - 動的なコンテンツでの MathJax
http://docs.mathjax.org/en/v3.0-latest/advanced/typeset.html
3 のバージョンでは、Mathjax
のロードと設定方法が異なります。
v2 から v3 へのアップグレード:http://docs.mathjax.org/en/latest/upgrading/v2.html
ロード時には、異なる設定の js を直接ロードすることができます。?config=xxx
は不要です。たとえば、https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
をロードします。
Mathjax.Hub
メソッドは削除され、設定は単にwindow.Mathjax
に設定オブジェクトを割り当てるだけです。
公式では、設定を変換するためのツールも提供しています: MathJax Configuration Converter
設定の例を示します:
(window as any).MathJax = {
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']],
},
options: {
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'code', 'a'],
},
chtml: {
scale: 1.2,
},
startup: {
ready: () => {
(window as any).MathJax.startup.defaultReady();
(window as any).MathJax.startup.promise.then(() => {
console.log('MathJax initial typesetting complete');
});
},
},
};
Mathjax
スクリプトがロードされると、window.Mathjax
を設定として読み取り、Mathjax
オブジェクトに置き換えます。その後、関連する関数を呼び出すことができます。
Mathjax
が初期化されると、設定のstartup.ready
メソッドが呼び出されます。ここで、ヒントやその他の設定を行うことができます。
問題は同じですが、DOM が更新されるとMathjax
は再レンダリングされません。MathJax.typesetPromise()
メソッドを使用する必要があります。componentDidUpdate
で設定してください。
componentDidUpdate() {
const MathJax = (window as any).MathJax;
if (MathJax) {
MathJax.typesetPromise && MathJax.typesetPromise();
}
}
このメソッドは非同期メソッドであり、同じ機能を持つ同期メソッドMathJax.typeset()
もあります。