15

I want to render the react components with a string as the input which i am receiving dynamically from another page. BUt i will have the references for the react components. Here is the example

Page1:
-----------------------------
loadPage('<div><Header value=signin></Header></div>');

Page2:
--------------------------------
var React =require('react');
var Header = require('./header');

var home = React.createClass({

loadPage:function(str){ 

           this.setState({
             content : str 
           });

  },

 render : function(){

  return {this.state.content}
 }

});

In this example i am receiving Header component as string , and i have the reference of Header component in my receiving page . How can i substitute the string with the actual react component

jazean
  • 171
  • 1
  • 2
  • 8
  • What is your use case exactly? The pattern you provide is very uncommon, and I don't think you can convert your string into components. Why don't you use some string id as arg in your loadPage() function, then render (real) components accordingly in your render method? – pierrepinard_2 Apr 07 '16 at 09:56
  • 3
    Its a page editor , whatever the markup has been saved into the file has to be re rendered back into the page editor – jazean Apr 07 '16 at 10:05
  • 1
    Then you'd better store a json structure mirroring the components' tree than markup. If you have a look at how React components declaration look like without jsx, you'll see how to serialize it. For example `
    ` is under the hood: `React.createElement(Header, {key: value}, React.createElement(OtherComponent, null))`
    – VonD Apr 07 '16 at 10:18
  • I use html-to-react for this exact purpose, where I receive an arbitrary string of markup and custom tags, and convert it to React elements. The current version doesn't play well with self-closing/void tags, but a fix is waiting to be merged to the master branch: https://github.com/mikenikles/html-to-react – dannyjolie Apr 07 '16 at 10:19
  • Ok thx I understand your use case, then I would go for a solution like @VonD suggested: store a JSON structure that describes your components-tree. – pierrepinard_2 Apr 07 '16 at 10:25
  • As a starting point [this answer](https://stackoverflow.com/a/58626638/81723) uses the browsers DOMParser to convert text to Elements, and then converts the Elements to `createElement` calls. It would need to be extended to sanitise content and map `
    ` to your Header component.
    – Sly_cardinal Jun 23 '22 at 00:06

6 Answers6

11

This react-jsx-parser component looks like it will solve your problem

Jonathan Wickens
  • 739
  • 6
  • 13
9

To render a react component using a string you can use.

var MyComponent = Components[type + "Component"];
return <MyComponent />;

For more information check the response here : React / JSX Dynamic Component Name

Community
  • 1
  • 1
Aaleks
  • 4,283
  • 5
  • 31
  • 39
  • 1
    Hi @Aaleks How about props? How can I pass props to target component? – Phúc Hoàng Trương Apr 04 '18 at 11:04
  • @PhúcHoàngTrương props can be passed as usual: `` ([docs](https://reactjs.org/docs/jsx-in-depth.html#using-dot-notation-for-jsx-type)). This solution simply creates references to components. – CPHPython Jan 05 '21 at 12:55
3

Built-in way

Without any package You can use the built in react attribute dangerouslySetInnerHTML to pass your string, and it will render it as an HTML

function Component() {

    const stringElement = "<h1> My Title </h1>";

    return (
        <div dangerouslySetInnerHTML={{ __html: stringElement }}>
        </div>
    );
}

And it would work fine.

But try to avoid rendering text as much as possible, since it might expose you to XSS attacks, you should XSS clean the text or avoid this unless you have no choice

Abraham
  • 12,140
  • 4
  • 56
  • 92
  • why is it called that "dangerouslySetInnerHTML" lol? Is this bad practice? – bcstryker Feb 10 '22 at 19:52
  • Yeah, it makes your code vulnerable to XSS attacks. In which if you store a special string containing malicious javascript code, it will be executed when you dangerously set the inner html, to that string. – Abraham Feb 11 '22 at 17:23
2

If you can live with having all your components in one module, then this works pretty well:

   import * as widgets from 'widgets';
   var Type = widgets[this.props.componentId];
   ...
   <Type />

The wildcard import works like a cut-rate component registry.

Robert Moskal
  • 21,737
  • 8
  • 62
  • 86
0

one more way to use component

const a = {
    b: {
        icon: <component props />
    }
}

In render function

 return(
          {a.b.icon}
       )

This will render your component in your JSON object

pareshm
  • 4,874
  • 5
  • 35
  • 53
0

This string-to-react-component library can help you to achieve your desired functionality

Mohsen Biglari
  • 392
  • 3
  • 6