Monday, October 2, 2017

React - How to pass HTML tags in props?

Leave a Comment

I want to be able to pass text with HTML tags, like so:

<MyComponent text="This is <strong>not</strong> working." /> 

But inside of MyComponent's render method, when I print out this.props.text, it literally prints out everything:

This is <strong>not</strong> working. 

Is there some way to make React parse HTML and dump it out properly?

10 Answers

Answers 1

You can use mixed arrays with strings and JSX elements (see the docs here):

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} /> 

There's a fiddle here that shows it working: http://jsfiddle.net/7s7dee6L/

Also, as a last resort, you always have the ability to insert raw HTML but be careful because that can open you up to a cross-site scripting (XSS) attack if aren't sanitizing the property values.

Answers 2

You can use dangerouslySetInnerHTML

Just send the html as a normal string

<MyComponent text="This is <strong>not</strong> working." /> 

And render in in the JSX code like this:

<h2 className="header-title-right wow fadeInRight"     dangerouslySetInnerHTML={{__html: props.text}} /> 

Just be careful if you are rendering data entered by the user. You can be victim of a XSS attack

Here's the documentation: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

Answers 3

<MyComponent text={<span>This is <strong>not</strong> working.</span>} /> 

and then in your component you can do prop checking like so:

import React from 'react'; export default class MyComponent extends React.Component {   static get propTypes() {     return {       text: React.PropTypes.object, // if you always want react components       text: React.PropTypes.any, // if you want both text or react components     }   } } 

Make sure you choose only one prop type.

Answers 4

For me It worked by passing html tag in props children

<MyComponent>This is <strong>not</strong> working.</MyComponent>   var MyComponent = React.createClass({     render: function() {     return (       <div>this.props.children</div>     );    }, 

Answers 5

Actually, there are multiple ways to go with that.

You want to use JSX inside your props

You can simply use {} to cause JSX to parse the parameter. The only limitation is the same as for every JSX element: It must return only one root element.

myProp={<div><SomeComponent>Some String</div>} 

The best readable way to go for this is to create a function renderMyProp that will return JSX components (just like the standard render function) and then simply call myProp={this.renderMyProp()}

You want to pass only HTML as a string

By default, JSX doesn't let you render raw HTML from string values. However, there is a way to make it do that:

myProp="<div>This is some html</div>" 

Then in your component you can use it like that:

<div dangerouslySetInnerHTML={this.props.myProp}></div> 

Beware that this solution 'can' open on cross-site scripting forgeries attacks. Also beware that you can only render simple HTML, no JSX tag or component or other fancy things.

The array way

In react, you can pass an array of JSX elements. That means:

myProp={["This is html", <span>Some other</span>, "and again some other"]} 

It wouldn't recommend this method because:

  • It will create a warning (missing keys)
  • It's not readable
  • It's not really the JSX way, it's more a hack than an intended design.

The children way

Adding it for the sake of completeness but in react, you can also get all children that are 'inside' your component.

So if I take the following code:

<SomeComponent>     <div>Some content</div>     <div>Some content</div> </SomeComponent> 

Then the two divs will be available as this.props.childrens in SomeComponent and can be rendered with the standard {} syntax.

This solution is perfect when you have only one HTML content to pass to your Component (Imagine a Popin component that only takes the content of the Popin as children).

However, if you have multiple contents, you can't use children (or you need at least to combine it with another solution here)

Answers 6

You can do it in 2 ways that I am aware of.

1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />

And then do this

class MyComponent extends React.Component {    render () {      return (<div>{this.props.text}</div>)    } } 

Or second approach do it like this

2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>

And then do this

class MyComponent extends React.Component {    render () {      return (<div>{this.props.children}</div>)    } } 

Answers 7

You could also use a function on the component to pass along jsx to through props. like:

 var MyComponent = React.createClass({     render: function() {     return (       <OtherComponent         body={this.body}       />     );    },     body() {      return(        <p>This is <strong>now</strong> working.<p>      );    }  });  var OtherComponent = React.createClass({    propTypes: {     body: React.PropTypes.func   },    render: function() {      return (         <section>           {this.props.body()}         </section>      );   },  }); 

Answers 8

In my project I had to pass dynamic html snippet from variable and render it inside component. So i did the following.

defaultSelection : {     innerHtml: {__html: '<strong>some text</strong>'} } 

defaultSelection object is passed to component from .js file

<HtmlSnippet innerHtml={defaultSelection.innerHtml} /> 

HtmlSnippet component

var HtmlSnippet = React.createClass({   render: function() {     return (       <span dangerouslySetInnerHTML={this.props.innerHtml}></span>     );   } }); 

Plunkr example

react doc for dangerouslySetInnerHTML

Answers 9

Yes, you can it by using mix array with strings and JSX elements. reference

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} /> 

Answers 10

Have appended the html in componentDidMount using jQuery append. This should solve the problem.

 var MyComponent = React.createClass({     render: function() {          return (            <div>             </div>         );     },     componentDidMount() {         $(ReactDOM.findDOMNode(this)).append(this.props.text);     } }); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment