3

Goal: I want to convert strings including React components into fully-functional JSX.

The easier example, for which there are many solutions on Stack Overflow, is this:

render()
{
  let txt = "<span><b>Hello World!</b></span>";

  return <div dangerouslySetInnerHTML={{__html: txt}}></div>;
    //---OR---
  return ReactHtmlParser(txt); //using react-html-parser
    //---OR---
  return parse(txt); //using html-react-parser
}

But if instead, let txt = "<MyComponent/>";, where MyComponent is a custom React component, I cannot find a way for the browser to interpret that correctly.

Using some methods, it will enter the DOM as lowercase <mycomponent><mycomponent/>. With other tricks, I can get it into the DOM as uppercase <MyComponent><MyComponent/>. But the browser will not interpret MyComponent as a React component, and will not execute the code inside.

I'm not interested in the answer React.createElement() because I don't want to use this for one component at a time. I want to parse long strings of JSX.

howrad
  • 1,066
  • 2
  • 12
  • 32
  • 1
    Have you looked at [MDX](https://mdxjs.com/)? It's an extension of markdown, but still ought to satisfy your use case. – backtick Oct 04 '20 at 05:16
  • @backtick thanks for showing me MDX. You're right, it may satisfy my use case, I'll investigate further. – howrad Oct 04 '20 at 17:38
  • @backtick the Introduction and Playground pages of mdxjs.com basically do what I want, by having a – howrad Oct 04 '20 at 21:58
  • Here's the [source](https://github.com/mdx-js/mdx/blob/master/packages/gatsby-theme-mdx/src/components/playground-editor.js) for the playground page. – backtick Oct 05 '20 at 18:34
  • @howrad any luck so far? – aldobsom Oct 18 '20 at 14:17
  • @aldobsom [MDX](https://mdxjs.com) and [React Live](https://react-live.netlify.app/) are both very promising. You have to pass custom React components into their scope. – howrad Oct 28 '20 at 19:13
  • See - https://stackoverflow.com/questions/39758136/render-html-string-as-real-html-in-a-react-component – Steve Tomlin Apr 08 '21 at 12:06

2 Answers2

0

There is no library which parses a string containing custom React component.

If you think about it, such library needs to be aware of your components locations as it needs to import and render it. Moreover, the actual name of the components is meaningless in React, you must have its instance available in scope.

Therefore your only solution is to write a custom parser for your own.

Such solution will roughly hold a dictionary which maps string to their components (need to handle props and duplicate naming too).

import {MyComponent,Button} from 'components';

export const Components = {
   MyComponent,
   Button
};

myParser('<MyComponent/>'); // Match MyComponent

You can use ReactDOMServer hence you have the element instance to render its HTML.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Dennis, what does JSFiddle use when you make a React fiddle? At some level, it must be executing React code that comes in as a string in the browser. – howrad Oct 04 '20 at 17:35
  • Its not, it just runs a machine on other server – Dennis Vash Oct 04 '20 at 18:37
  • @DennisVash actually, that's exactly what `react-jsx-parser` does, and as you say, it does so by allowing the implementor to provide a mapping of names to component functions. The parser then acts, essentially, as a run-time interpreter of Jsx and binds to any component that is either turning into native HTML or which has been provided in the map. I'm the author of the lib, so I'm biased - but it may be a good solution to this problem. – Troy Alford Oct 21 '21 at 17:50
0

You can use -

  • html-react-parser
  • react-jsx-parser
Steve Tomlin
  • 3,391
  • 3
  • 31
  • 63