338

I am building something with React where I need to insert HTML with React Variables in JSX. Is there a way to have a variable like so:

var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';

and to insert it into react like so, and have it work?

render: function() {
    return (
        <div className="content">{thisIsMyCopy}</div>
    );
}

and have it insert the HTML as expected? I haven't seen or heard anything about a react function that could do this inline, or a method of parsing things that would allow this to work.

0

10 Answers 10

453

You can use dangerouslySetInnerHTML, e.g.

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}
Sign up to request clarification or add additional context in comments.

8 Comments

How does this work if you need to add something to <head>?
Normal DOM methods in componentDidMount should work, I've not done it before though.
@DanielleMadeley Are you trying to insert conditional IE comments into <head>? If so, I've had success using the trick described here: nemisj.com/conditional-ie-comments-in-react-js
Make sure you pass a method to the dangerouslySetInnerHTML and not a hash. According to the docs, it's dangerous to just pass a hash. Reference: facebook.github.io/react/tips/dangerously-set-inner-html.html
Is there a way without inserting the div?
|
158

Note that dangerouslySetInnerHTML can be dangerous if you do not know what is in the HTML string you are injecting. This is because malicious client side code can be injected via script tags.

It is probably a good idea to sanitize the HTML string via a utility such as DOMPurify if you are not 100% sure the HTML you are rendering is XSS (cross-site scripting) safe.

Example:

import DOMPurify from 'dompurify'

const thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div>
    );
}

3 Comments

@vsync nope it shouldn't :)
is it possible to render not only html tags but tag from library like material ui Alert tag. i want the code to be like this import DOMPurify from 'dompurify' const thisIsMyCopy = '<Alert severity="warning">copy copy copy <strong>strong copy</strong></Alert >'; render: function() { return ( <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div> ); }
@sasharomanov, Did you get any solution for this scenario ?
78

dangerouslySetInnerHTML has many disadvantage because it set inside the tag.

I suggest you to use some react wrapper like i found one here on npm for this purpose. html-react-parser does the same job.

import Parser from 'html-react-parser';
var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content">{Parser(thisIsMyCopy)}</div>
    );
}

Very Simple :)

UPDATE

in the latest version as usage explained:

// ES Modules
import parse from 'html-react-parser';

// CommonJS
const parse = require('html-react-parser');
....

//Parse single element
parse('<li>Item 1</li><li>Item 2</li>');

//Parse multiple elements
parse('<li>Item 1</li><li>Item 2</li>');

2 Comments

"dangerouslySetInnerHTML has many disadvantage because it set inside the tag." Can you explain more about this. Trying to think out what fundamental difference there is between html-react-parser and sanatized innerHtml
It seems that html-react-parser doesn't sanitize the input - see the FAQ
64

By using '' you are making it to a string. Use without inverted commas it will work fine.

const App = () => {
const span = <span> whatever your string </span>

const dynamicString = "Hehe";
const dynamicStringSpan = <span> {`${dynamicString}`} </span>

  return (
    <div>

      {span}

      {dynamicStringSpan}

    </div>
  );

};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

3 Comments

By far the simplest answer especially if the HTML is written by you and dynamic based on user input. You can quite literally set var myHtml = <p>Some text</p>; and it works
I thought it would be for a dynamically generated string (e.g. from user generated content) where your solution would not work. But thanks!
This only works for wrapped strings. You couldn't for instance ad a <br /> tag to the text so this solution does not answer the question.
8

To avoid linter errors, I use it like this:

  render() {
    const props = {
      dangerouslySetInnerHTML: { __html: '<br/>' },
    };
    return (
        <div {...props}></div>
    );
  }

Comments

8
import { Fragment } from 'react' // react version > 16.0

var thisIsMyCopy = (
  <Fragment>
    <p>copy copy copy&nbsp;
    <strong>strong copy</strong>
    </p>
  </Fragment>
)

By using '' the sets the value to a string and React has no way of knowing that it is a HTML element. You can do the following to let React know it is a HTML element -

  1. Remove the '' and it would work
  2. Use <Fragment> to return a HTML element.

3 Comments

This does not answer the question. The content of thisIsMyCopy is itself JSX, not a string of HTML. So you're literally pasting JSX into JSX.
You can find Fragments in the Preact too but only in version X and on.
I think this is the best way because we don't have to store it as a string variable with this approach. Also keep in mind that dangerouslySetInnerHTML is dangerous to use because malicious client side code can be injected via script tags: stackoverflow.com/a/42380982/6908282
7

You don't need any special library or "dangerous" attribute. You can just use React Refs to manipulate the DOM:

class MyComponent extends React.Component {
    
    constructor(props) {
        
        super(props);       
        this.divRef = React.createRef();
        this.myHTML = "<p>Hello World!</p>"
    }
    
    componentDidMount() {
        
        this.divRef.current.innerHTML = this.myHTML;
    }
    
    render() {
        
        return (
            
            <div ref={this.divRef}></div>
        );
    }
}

A working sample can be found here:

https://codepen.io/bemipefe/pen/mdEjaMK

1 Comment

Good one, and you can even use this.divRef.current.outerHTML = this.myHTML; to avoid the extra div. However, createRef requires React 16.3, that is not always an option, for instance with SPFx for SharePoint 2019 on-prem...
0

Try Fragment, if you don't want any of above.

In your case, we can write

import React, {useState, Fragment} from 'react'

const thisIsMyCopy = Fragment('<p>copy copy copy <strong>strong copy</strong></p>')

render: function() {
    return (
        <div className="content">{thisIsMyCopy}</div>
    );
}

If you using hook want to set it in a state somewhere with any condition

const [thisIsMyCopy, setThisIsMyCopy] = useState(<Fragment><p>copy copy copy <strong>strong copy</strong></p></Fragment>);

2 Comments

The library you are referencing is not part of React, but in your code you're importing Fragment from React. Your snippet throws an error.
the link you provided shows that it is fragment with a lowercase f and does not show where you are importing it from.
-5

If anyone else still lands here. With ES6 you can create your html variable like so:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}

3 Comments

and if you want variables inside your string, you'll need to wrap each in {} and the whole string in some markup like so (<span>{telephoneNumber} <br /> {email}</span>)
This is different from what's asked in the question. In the question <p>copy copy copy <strong>strong copy</strong></p> is a string. You have it as JSX.
That is not ES6, but JSX
-7

You can also include this HTML in ReactDOM like this:

var thisIsMyCopy = (<p>copy copy copy <strong>strong copy</strong></p>);

ReactDOM.render(<div className="content">{thisIsMyCopy}</div>, document.getElementById('app'));

Here are two links link and link2 from React documentation which could be helpful.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.