Search code examples
javascripthtmlreactjsscript-tag

React: Script tag not working when inserted using dangerouslySetInnerHTML


I'm trying to set html sent from my server to show inside a div using dangerouslySetInnerHTML property in React. I also have script tag inside it and use functions defined in same inside that html. I have made example of error in JSFiddle here.

This is test code:

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var Hello = React.createClass({
  displayName: 'Hello',
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

I checked and the script tag is added to DOM, but cannot call the functions defined within that script tag. If this is not the correct way is there any other way by which I can inject the script tag's content.


Solution

  • Here's a bit of a dirty way of getting it done , A bit of an explanation as to whats happening here , you extract the script contents via a regex , and only render html using react , then after the component is mounted the content in script tag is run on a global scope.

    var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';
    
    var extractscript=/<script>(.+)<\/script>/gi.exec(x);
    x=x.replace(extractscript[0],"");
    
    var Hello = React.createClass({
      displayName: 'Hello',
      componentDidMount: function() {
        // this runs the contents in script tag on a window/global scope
        window.eval(extractscript[1]);
    
      },
      render: function() {
        return (<div dangerouslySetInnerHTML={{__html: x}} />);
      }
    });
    
    ReactDOM.render(
      React.createElement(Hello),
      document.getElementById('container')
    );