React - How to pass HTML tags in props?

Reactjs

Reactjs Problem Overview


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?

Reactjs Solutions


Solution 1 - Reactjs

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.

Solution 2 - Reactjs

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=myProp={{ __html: this.renderMyProp() }}></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"]}

I 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.children 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)

Solution 3 - Reactjs

From React v16.02 you can use a Fragment.

<MyComponent text={<Fragment>This is an <strong>HTML</strong> string.</Fragment>} />

More info: https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html

Solution 4 - Reactjs

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

Solution 5 - Reactjs

<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.

Solution 6 - Reactjs

On a client-side react application, there are a couple of ways of rendering a prop as a string with some html. One safer than the other...

1 - Define the prop as jsx (my preference)

const someProps = {
  greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)

• The only requirement here is that whatever file is generating this prop needs to include React as a dependency (in case you're generating the prop's jsx in a helper file etc).

2 - Dangerously set the innerHtml

const someProps = {
  greeting: '<React.Fragment>Hello<a href="/${name_profile}">${name_profile}</a></React.Fragment>'
}

const GreetingComponent = props => {
  const innerHtml = { __html: props.someProps.greeting }
  return <p dangerouslySetInnerHtml={innerHtml}></p>
}

• This second approach is discouraged. Imagine an input field whose input value is rendered as a prop in this component. A user could enter a script tag in the input and the component that renders this input would execute this potentially malicious code. As such, this approach has the potential to introduce cross-site scripting vulnerabilities. For more information, refer to the official React docs

Solution 7 - Reactjs

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>
    );
   },

Solution 8 - Reactjs

Set the text prop type to any and do this:

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>

Example

Solution 9 - Reactjs

You can use the <></> Fragments to pass the HTML in the props.

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

Reference: https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html#jsx-fragment-syntax

Solution 10 - Reactjs

You can successfully utilize React fragments for this task. Depending on the React version you use, you can use short syntax: <> or the full tag: <React.Fragment>. Works especially well if you don't want to wrap entire string within HTML tags.

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />

Solution 11 - Reactjs

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>)
   }
}

Solution 12 - Reactjs

Parser from html-react-parser is a good solution. You just have to

  • install it with npm or yarn

  • import Parser from 'html-react-parser';

  • call it with :

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

and it works well.

Solution 13 - Reactjs

@matagus answer is fine for me, Hope below snippet is helped those who wish to use a variable inside.

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />

Solution 14 - Reactjs

Do like this:

const MyText = () => {
     return (
          <>
               This is <strong>Now</strong> working.
          </>
     )
}

then pass it as a props as:

<MyComponent Text={MyText} />

now you can use it in your component:

const MyComponent = ({Text}) => {
     return (
          <>
               // your code
               {<Text />}
               // some more code
          </>
     )
 }

Solution 15 - Reactjs

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>
     );
  },
   
});

Solution 16 - Reactjs

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

Solution 17 - Reactjs

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

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

Solution 18 - Reactjs

Adding to the answer: If you intend to parse and you are already in JSX but have an object with nested properties, a very elegant way is to use parentheses in order to force JSX parsing:

const TestPage = () => (
  <Fragment>
    <MyComponent property={
    {
      html: (
        <p>This is a <a href='#'>test</a> text!</p>
      )
    }}>
    </MyComponent>
  </Fragment>
);

Solution 19 - Reactjs

This question has already a lot of answers, but I had was doing something wrong related to this and I think is worth sharing:

I had something like this:

export default function Features() {
  return (
    <Section message={<p>This is <strong>working</strong>.</p>} />
  }
}

but the massage was longer than that, so I tried using something like this:

const message = () => <p>This longer message is <strong>not</strong> working.</p>;

export default function Features() {
  return (
    <Section message={message} />
  }
}

It took me a while to realize that I was missing the () in the function call.

Not working

<Section message={message} />

Working

<Section message={message()} />

maybe this helps you, as it did to me!

Solution 20 - Reactjs

We can do the same thing in such a way.

const Child = () => {
  return (
     write your whole HTML here.
  )
}

now you want to send this HTML inside another component which name is Parent component.

Calling :-

<Parent child={<child/>} >
</Parent> 

Use Of Child:-

 const Parent = (props) => {
   const { child } = props; 
   return (
       {child}
    )
}

this work perfect for me.

Solution 21 - Reactjs

Here is a solution that doesn't use the dangerouslySetInnerHTML which is dangerous as the name says.

import { IntlProvider, FormattedMessage } from "react-intl";

<FormattedMessage
          id="app.greeting"
          description="Bold text example"
          defaultMessage="Look here, I can include HTML tags in plain string and render them as HTML: <b>Bold</b>, <i>Italics</i> and <a>links too</a>."
          values={{
            b: (chunks) => <b>{chunks}</b>,
            i: (chunks) => <i>{chunks}</i>,
            a: (chunks) => (
              <a class="external_link" target="_blank" href="https://jiga.dev/">
                {chunks}
              </a>
            )
          }}
        />

This should be rendered as:

react jiga.dev

Full example in https://jiga.dev/react-render-string-with-html-tags-from-props/

Solution 22 - Reactjs

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);
    }
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionffxsamView Question on Stackoverflow
Solution 1 - ReactjsmatagusView Answer on Stackoverflow
Solution 2 - ReactjsAtrakeurView Answer on Stackoverflow
Solution 3 - Reactjslaszlo-horvathView Answer on Stackoverflow
Solution 4 - ReactjshecontrerasoView Answer on Stackoverflow
Solution 5 - Reactjsuser670839View Answer on Stackoverflow
Solution 6 - ReactjsVijay Selvan RamView Answer on Stackoverflow
Solution 7 - ReactjsShashi3456643View Answer on Stackoverflow
Solution 8 - ReactjsAmey ParundekarView Answer on Stackoverflow
Solution 9 - ReactjsOSMQuoteView Answer on Stackoverflow
Solution 10 - ReactjsCycloneView Answer on Stackoverflow
Solution 11 - ReactjsAdeel ImranView Answer on Stackoverflow
Solution 12 - ReactjsFranck212View Answer on Stackoverflow
Solution 13 - ReactjsJaison JamesView Answer on Stackoverflow
Solution 14 - ReactjsFarasat AliView Answer on Stackoverflow
Solution 15 - ReactjsAllisonView Answer on Stackoverflow
Solution 16 - ReactjsRajView Answer on Stackoverflow
Solution 17 - ReactjsOsama BariView Answer on Stackoverflow
Solution 18 - ReactjsNick LouloudakisView Answer on Stackoverflow
Solution 19 - ReactjsabranheView Answer on Stackoverflow
Solution 20 - ReactjspushparmarView Answer on Stackoverflow
Solution 21 - ReactjsLenin Raj RajasekaranView Answer on Stackoverflow
Solution 22 - ReactjsKaushikView Answer on Stackoverflow