Some solutions use dangerouslySetInnerHtml
, but it only allows HTML parsing. I am trying to insert a combination of HTML and React components with dynamic variable, for example the code below has a string that has some text, HTML, a MathJax component, and some variables. All these in a string that I want the Parent React Component to parse.
import { useState } from "react";
import MathJax from "react-mathjax";
import { lhospital } from "./equations/equations";
function App() {
const [text, setText] = useState(`<i>count</i>`);
<MathJax.Provider>
<div dangerouslySetInnerHTML: {{__html: `<strong>L'hospital</strong>: <MathJax.Node formula={lhospital} />`}} />
</MathJax.Provider>
}
export default App
2
Answers
Instead of Using above approach, I’ll implement this bellow
We tend to think of JavaScript as a dynamic, interpreted language — which it is — but if you’re using any of the standard tooling to bundle your React app (as you absolutely should be, and do seem to be), then there’s also a static compilation step, and that step is very likely to rename any local variables, React components, and so on, and to remove any that aren’t used.
This means that what you describe is theoretically impossible: at runtime, in the browser, when you go to parse the JSX string that you’ve stored, anything like
<MyComponent />
or{myVariable}
in that string is liable to be meaningless.But "theoretically impossible" really just means "impossible in the general case". If there are specific components that you’re interested in (e.g.
MathJax.Node
) and specific variables that you’re interested in (e.g.lhospital
), then you can write code that specifically handles those. The code that you write will refer to those components and variables in a way that the compilation step will see and maintain.But you wouldn’t want to write a full JSX parser; that’s just not a reasonable amount of work. For one thing, JSX can embed arbitrary JavaScript expressions (inside
{...}
), which in turn can contain JSX, so a full JSX parser would have to support things likeand then, once you’ve parsed that, you’d need your own logic to essentially implement all of JavaScript inside JavaScript.
This is possible — it’s essentially what @babel/standalone does — but it’s a huge amount of work, and so many things can go wrong. I can’t imagine you want to be in the business of doing that.
Instead, I think you should, first, think about whether you really need this kind of dynamically-stored code. (You might want to ask a new question about your underlying goal, to see if anyone can suggest a better way to achieve that goal.)
If you decide that you really do need this kind of dynamically-stored code, then you should figure out the specific things you want to support, and then come up with a specific way to represent those things, either as a well-defined subset of JSX or using your own format. One option might be to represent everything in JSON, which (downside) would be more verbose but (upside) makes parsing very simple.
For example, if you want to support the equivalent of:
then a JSON representation might be:
You’d then have a function that takes three arguments:
and performs the requisite substitutions, returning a React element as the result. This function would use React.createElement to create the actual React elements (both for HTML elements and for React components).
That function could look like this:
and could be used like this: