我正在构建一个网络应用程序,它在某些输入中使用用户可写的 LaTeX 将其动态显示到另一个 div 中或在同一输入中替换它。
我一直在尝试将 Mathquill 与 NextJS v13.3.0 一起使用,我发现这个 npm 包可以解决 React 的问题,称为“React-Mathquill”(https://www.npmjs.com/package/react-mathquill ),但是根据作者的说法,由于 SSR(服务器端渲染),这不起作用,他建议导入没有 SSR 的包(https://github.com/viktorstrate/react-mathquill/issues/49) 。问题是,我完全不明白如何做到这一点,我已经根据 NoSSR 阅读了文档(https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#with -no-ssr)但似乎有点难以理解并且不确定如何做到这一点。
如果有人知道如何解决这个问题,或者有另一个库的不同解决方案或其他库来显示与 Next 兼容的复杂数学方程(即使没有 LaTeX),我会感谢您的分享
这是我尝试过的:
import React, { useState } from 'react'
import { addStyles, EditableMathField } from 'react-mathquill'
addStyles()
function Test()
{
const [latex, setLatex] = useState('\\frac{1}{\\sqrt{2}}\\cdot 2')
return (
<div>
<EditableMathField
latex={latex}
onChange={(mathField) => {
setLatex(mathField.latex())
}}
/>
<p>{latex}</p>
</div>
)
}
export default Test
但出现此错误:
Server Error ReferenceError: window is not defined
在研究其他库和一些失败之后,我找到了 MathJax 并制定了这个解决方案,当指定的 LaTeX 更改时重新分析页面的每个元素:
import Head from 'next/head';
import { useEffect, useState } from 'react'
function Test()
{
const [latex, setLatex] = useState("");
const handleChange = ( { target: { value } }) =>
{
setLatex(value)
}
const mathJaxReanalyze = async () =>
{
if (typeof window !== 'undefined' && window.MathJax)
{
try
{
await window.MathJax.typesetPromise();
}
catch(e)
{
console.log("MatJax error: " + e);
}
}
}
useEffect(() =>
{
mathJaxReanalyze();
}, [latex])
return (
<>
<Head>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</Head>
<div>
<input onChange={handleChange}/>
<p>{latex}</p>
</div>
</>
)
}
export default Test
它不像使用 MathQuill 那样干净,但对我有用
编辑:最近注意到解决方案的评论,但如果有人发现它有用,我会留下这个答案
根据这篇文章Next.js:窗口未定义,一些库只是通过导入来引用
window
,因此必须通过其他方式使用它们,在这种情况下,函数addStyles
是问题所在。由于 MathQuill 提供了它的样式表,我可以通过这种方式从项目的 public
文件夹中添加它
import { useState } from 'react'
import dynamic from 'next/dynamic';
import Head from 'next/head';
const EditableMathField = dynamic(() => import("react-mathquill"), { ssr: false })
function Test()
{
const [latex, setLatex] = useState('\\frac{1}{\\sqrt{2}}\\cdot 2')
return (
<>
<Head>
<link rel="stylesheet" href="/mathquill.css"/>
</Head>
<div>
<EditableMathField
latex={latex}
onChange={(mathField) =>
{
setLatex(mathField.latex())
}}
/>
<p>{latex}</p>
</div>
</>
)
}
export default Test
"use client";
import dynamic from "next/dynamic";
import { useEffect } from "react";
import { MathField } from "react-mathquill";
const EditableMathField = dynamic(
() => import("react-mathquill").then((mod) => mod.EditableMathField),
{ ssr: false }
);
const YourComponent = () => {
useEffect(() => {
import("react-mathquill").then((mq) => {
mq.addStyles();
});
}, []);
// ...rest of your component
}
您可以像这样导入addStyles。我遇到了类似的问题,Next.js 也不鼓励在组件中使用手动样式表标签,因此我猜不建议使用 Head