StateLess
StateLess

Reputation: 5402

weird html rendering issue with react

I'm trying to render the message with html tags inside it. The rendering is working fine if the string is passed as prop, but when the same is passed from a variable the display text has encoded text.

Any idea how do I get it working in both scenarios.?

class Hello extends React.Component {
  render() {
    console.log(this.props.name)
    return <div>{this.props.name}</div>;
  }
}

ReactDOM.render(
  <Hello name="&lt;p&gt;How are you?&lt;/p&gt;" />,
  document.getElementById('container') --> **<p>How are you?</p>** 
);


class HelloOther extends React.Component {
  render() {
    const name = "&lt;p&gt;How are you?&lt;/p&gt;" 
    return <Hello name={name} />;
  }
}

ReactDOM.render(
  <HelloOther />,
  document.getElementById('container2') -- &lt;p&gt;How are you?&lt;/p&gt; -- > why?
);

Fiddle link - https://jsfiddle.net/d6s7be1f/2/

Upvotes: 3

Views: 338

Answers (2)

Yousaf
Yousaf

Reputation: 29282

From React Docs:

In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.

Unless you want to use dangerouslySetInnerHTML, you could use a regex to wrap the string with html tags. This way, you don't have to pass html entities in the string. You just pass the string and wrap the string with html tag using .replace() function.

Since you also want the string to be parsed as HTML, you could pass an extra prop to the Hello component that is then used to wrap the string with the desired html tag and also render the string nested within the desired html tag

function HTMLTag({ tag, children }) {
  return React.createElement(tag, null, children);
}

class Hello extends React.Component {
  render() {
    const { name, tag } = this.props;
    const str = name.replace(/(.+)/, `<${tag}>$1</${tag}>`);
    return ( 
        <div>
        <HTMLTag tag={tag}>{str}</HTMLTag>
        </div>
    );
  }
}

class HelloOther extends React.Component {
  render() {
    const name = "How are you?"; 
    return <Hello name={name} tag="h3" />;
  }
}

ReactDOM.render(
  <Hello name="How are you?" tag="p" />,
  document.getElementById('container')
);

ReactDOM.render(
  <HelloOther />,
  document.getElementById('container2')
);
<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="container"></div>
<div id="container2"></div>

Upvotes: 2

Vagan M.
Vagan M.

Reputation: 463

class Hello extends React.Component {
  createMarkup() {
    return {__html: this.props.name};
  }
  render() {
    return <div dangerouslySetInnerHTML={this.createMarkup()} />;
  }
}

Upvotes: 2

Related Questions