MathJax в React, как убедиться, что обновления страницы отображаются в Latex правильно?

#javascript #html #reactjs #mathjax

#javascript #HTML #reactjs #mathjax

Вопрос:

Для некоторого контекста в моем HTML я импортировал исходный код MathJax в первом теге script:

 <html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <script type="text/javascript" async src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [["$", "$"], ["\(", "\)"]],
        displayMath: [["$$", "$$"]], ["\[", "\]"]
        processEscapes: true
    }
});
</script>
    <script type="text/javascript" src="https://cdnjs.loli.net/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>Ne computational engine</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
  

И я создал компонент React:

 

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

  componentDidMount(){
    this.renderMath();
  }

  componentDidUpdate(){
    this.renderMath();
  }

  renderMath(){
    window.MathJax.Hub.Queue([
      "Typeset",
      window.MathJax.Hub,
      this.node.current
    ]);
  }

  render(){
    const {text} = this.props;
    return <div ref = {this.node}> {this.props.children}</div>;
  }
}

export default Latex;
  

Чтобы я мог вложить в нее свой компонент приложения:

 ReactDOM.render(
  <Latex>
    <App />
  </Latex>,
  document.getElementById('root')
);
  

Он отлично работает при первом монтировании компонента, поэтому, если у меня есть, скажем, $ $ phi $ $ внутри тега в моем компоненте приложения, он будет отображаться в Latex полностью нормально.

Однако в другом компоненте React, который извлекает данные из серверной части после отправки формы, а затем отображает ее, ни один из отображаемых данных не отображается в Latex.

Для добавления данных у меня есть следующий компонент и вспомогательные функции, которые очень запутанны, но работают нормально. (помимо того факта, что mathjax, похоже, не переводит текст в Latex)

 class CLI extends React.Component{
  constructor(props){
    super(props)
    this.state = {value: '',
                  interepreted: '',
                label: ''}

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  }

  handleChange(event){
    this.setState({value: event.target.value})
  }

  handleSubmit(event){

    event.preventDefault()
    const url = "/input"

    const ul = document.getElementById("ul-info")
    let resp = ""
  fetch(url "/commands", {method: "POST", body: JSON.stringify(this.state.value),
  headers: new Headers({
    "content-type": "application/json"
  })}
  ).then(function(response) {
  resp = response
  response.json().then(function(data) {

    console.log(data);
    process_commands(ul,data)


  });
})
.catch(function(error) {
  console.log("Fetch error: "   error);
});
  }

  render(){
    return(
      <form onSubmit = {this.handleSubmit}>
        <label>
          <textarea value ={this.state.value}
            onChange = {this.handleChange} draggable = "false" cols = "70" rows = "2"/>
            <input type = "submit" value = "=" />

        </label>

      </form>
    )
  }
}
  

наряду со следующими вспомогательными функциями:

 function createNode(element){
  return document.createElement(element);
}

function append(parent,el){
  return parent.appendChild(el);
}

function process_commands(ul,data){
  var n;
  var i;
  var j;
  var k;
  for(n = 0; n<data.info.length;n  ){
    if(data.labels[n] != null){
    let label = createNode("h2");
    label.innerHTML = `${data.labels[n]}`;
    append(ul,label);
    }
    if(data.labels[n] == "zeroes" || data.labels[n] == "partialderivative" || data.labels[n] == "partialintegral"){
    for(i = 0; i <data.info[n].length;i  ){
      let sublabel = createNode("h3");
      sublabel.innerHTML = `${data.info[n][i][0]}`;
      append(ul,sublabel);
      for(j = 0; j<data.info[n][i][1].length; j  ){
        let sublabel_function  = createNode("h4");
        sublabel_function.innerHTML = `${data.info[n][i][1][j][0]}`;
        append(ul, sublabel_function);
        for(k=0; k<data.info[n][i][1][j][1].length; k  ){
          let solution = createNode("p");
          solution.innerHTML = `${data.info[n][i][1][j][1][k][0]}`   " : "   `${data.info[n][i][1][j][1][k][1]}`;
          append(ul,solution)
        }
      }
    }
  }
  }
}
  

Но компонент Latex не будет отображать ни один из этих вновь созданных тегов в Latex. Я думаю, что, возможно, я использую Mathjax не по назначению или добавляю новые HTML-теги способом, несовместимым с методом componentDidUpdate() компонента LatexReact. Я пытался выяснить, как решить эту проблему в течение нескольких часов, и я следил за другими публикациями здесь для MathJax, но ни в одной из них проблема не устранялась (или ни одно из исправлений ничего не изменило).

(Просто напоминаю, данные отображаются отлично, но в виде обычного текста, а не в Latex)

Комментарии:

1. Было бы очень полезно, если бы вы могли поместить свою программу в CodeSandbox

2. Поддерживает ли code sandbox серверную часть flask или мне придется переписать часть выборки для извлечения из другой серверной части?

3. Конечно, он поддерживает любой серверный интерфейс, если вы вызываете api с обычного URL

Ответ №1:

Согласно моему исследованию, Mathjax не верстается, даже если есть изменения в дочерних элементах, простая проверка здесь заключается в передаче одного реквизита компоненту Latex, будь то datetime или что-то еще, просто меняйте этот реквизит каждый раз, когда в вашем DOM происходят изменения, поэтому компонент LATEX получит изменение реквизита, что вызовет набор MathJax, у меня это сработало.