0

This link says Reactjs is progressive and can be added to a regular web app as follows:

Create a holder for the component:

<div id="root"></div>

Add React script tags to your header:

<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>

Load the React component:

<script src="mathjax.js"></script>

Create React Component (here is functional component in mathjax.js):

import React, { useState, useEffect } from 'react';
import { MathComponent } from 'mathjax-react';

const e = React.createElement;

const math_styles = {
    "color" : "black",
    "display" : "none"
}

function MathJax() {
    
    const [count, setCount] = useState("");

    return e(`
        <div style={math_styles}>
            <MathComponent tex={String.raw`${count}`} />
        </div>
        `)
}

const domContainer = document.querySelector('#root');
ReactDOM.render(e(LikeButton), domContainer);

export default MathJax;

Notice I added the wrap-around code as suggested in the link:

// at top
const e = React.createElement;

// at bottom
const domContainer = document.querySelector('#root');
ReactDOM.render(e(MathJax), domContainer);

I also tried adding type='module' to the script tag:

<script type="module" src="mathjax.js"></script>

But I get the following error:

Uncaught SyntaxError: missing ) after argument list

It seems as though the JSX in the React component is causing issues. But the example code in the link above shows encasing the JSX inside a template literal string as I have done.

Technically, the example in the link shows the passing of additional arguments like this:

return e(
  'button',
  { onClick: () => this.setState({ liked: true }) },
  'Like'
);

But I'm not sure how I would make this work for a functional component like the one in my example.

zhulien
  • 5,145
  • 3
  • 22
  • 36
Cybernetic
  • 12,628
  • 16
  • 93
  • 132

1 Answers1

-1

There is a huge difference between:

return e(
    'button',
    { onClick: () => this.setState({ liked: true }) },
    'Like'
);

and

return e(`
    <div style={math_styles}>
        <MathComponent tex={String.raw`${count}`} />
    </div>
`);

The syntax you're using is JSX and you're trying to include JSX in non-jsx aware environment/method which entirely defeats the purpose of the exercise. You should use either one or the other. JSX requires transpilation to normal javascript but avoids the pain of manually React.createElement-ing everything. The latter, on the other hand, runs everywhere as it is a valid javascript. There is no reason to combine the 2 approaches like that(and in most cases, it won't work at all). In your case it won't work for sure as you're not using any transpiler as babel to handle the job for you.

It's actually quite simple. Imagine that React.createElement just executes document.createElement under the hood(it's a bit more complicated, but it is a decent base for this particular case). In this context, what is expected from the engine when it encounters the following:

document.createElement(
    `<div style={math_styles}>
        <MathComponent tex={String.raw`${count}`} />
    </div>`
);

This is not a valid element. What element should the document create?!

JSX is syntactic sugar which is actually translated to the code you see in the first code sample.

So, when you transpile your JSX:

<div style={math_styles}>
    <MathComponent tex={String.raw`${count}`} />
</div>

it will be converted to:

React.createElement("div", {
    style: math_styles
}, React.createElement(MathComponent, {
    tex: String.raw`${count}`
}));

For the answer to be complete, your code is initially failing because you're closing the interpolated string prematurely by using a nested pair of ticks(`).

zhulien
  • 5,145
  • 3
  • 22
  • 36