ReactDOMServer not rendering components to string (third-party libraries - react-mathjax)

557 Views Asked by At

I'm using the package react-mathjax to include some math notations in a React component.

Due to a project specificity (which I won't go into here to simplify the question), I need to convert this component to a string and inject the html string into a div using dangerouslySetInnerHTML.

This is the component:

import MathJax from "react-mathjax";

const Math = () => (
  <MathJax.Provider>
    <MathJax.Node inline formula="x=2" />
  </MathJax.Provider>
);

For some reason when I try to convert it to a string using ReactDOMServer it doesn't work (it returns a empty string):

const html = ReactDOMServer.renderToString(<Math />); // first attempt

const htmlStaticMarkup = ReactDOMServer.renderToStaticMarkup(<Math />); // second attempt

If I render the Math component directly it works. And if I wrap the Math component with some default HTML tags and convert it to string, the default HTML tags are converted (but the Math component is ignored). So, there is no problem with the Math component neither with the ReactDOMServer to convert default HTML tags.

Any idea?

This is a demo using CodeSandbox: https://codesandbox.io/s/competent-payne-uvww0?file=/src/App.js

This is the full source code:

import ReactDOMServer from "react-dom/server";
import MathJax from "react-mathjax";

const Math = () => (
  <MathJax.Provider>
    <MathJax.Node inline formula="x=2" />
  </MathJax.Provider>
);

const CustomHtml = () => (
  <span>
    <Math />
    <p>Common HTML</p>
  </span>
);

const html = ReactDOMServer.renderToString(<CustomHtml />);
const htmlStaticMarkup = ReactDOMServer.renderToStaticMarkup(<CustomHtml />);

export default function App() {
  return (
    <>
      <p>Using the Math component and some default HTML directly: </p>
      <CustomHtml />

      <p>Using the Math component and some default HTML tags as a string (ReactDOMServer.renderToString): </p>
      <div dangerouslySetInnerHTML={{ __html: html }} />

      <p>Using the Math component and some default HTML tags as a string (ReactDOMServer.renderToStaticMarkup): </p>
      <div dangerouslySetInnerHTML={{ __html: htmlStaticMarkup }} />
    </>
  );
}
1

There are 1 best solutions below

1
Geet Laishram On

Add a function like this

const returnMathMl = (data) => {

    return (
      <span
        dangerouslySetInnerHTML={{
          __html: `${data}`.replace(/\n[\s]*/g, ''),
        }}
      />
    );
  };

and wrap your component with MathJax, your code should look something like this

const returnMathMl = (data) => {

    return (
      <span
        dangerouslySetInnerHTML={{
          __html: `${data}`.replace(/\n[\s]*/g, ''),
        }}
      />
    );
  };


return (
      <MathJax>
       {returnMathMl(myData)}
      </MathJax>
    );