4

I was wondering of I can create a script element using react, something like:

var reactScriptElement = React.createElement('script', {src: "d.js"});
ReactDOM.render(reactScriptElement, document.getElementById('button'));

But, the script is not run by the browser. However, doing it the native way, does seems to run it:

var script = document.createElement('script');
script.src = "./d.js";
var div = document.getElementById('button');
div.appendChild(script);

So, is it a bug, by design, or something I am doing wrong?

Edit: This is not a duplicate. The issue here is the difference between the two, why they are not acting the same.

2
  • Possible duplicate of Adding script tag to React/JSX Commented Dec 6, 2016 at 7:48
  • Definietly not. The issue here is the difference between the two, why they are not acting the same. Commented Dec 6, 2016 at 9:25

2 Answers 2

2

The difference is that the react version never gets inserted into the real Browser DOM Ast a so-called shallow copies of the react vdom does get into the DOM the original behavior gets not used because its a reference to a script at another place in the realDOM the dom doesn't know that this referenced copy got inserted as it is only aware of the original referenced dom node that is not inserted.

A Little Demo of whats happening in details note that the escaped version of the script end tag is needed to prevent browser parsing bugs when this code gets used on a single page

<div id="root"></div>
<script>
const el = document.getElementById('root')
const script =`<script src=d.js></${'script'}>`
console.log(script)
el.innerHTML= script
</script>

when I set the innerHTML with a tag it doesn't get executed while it is inserted into the dom. when the script would be in an extra file, not a script tag it could use innerHTML = '<script src=d.js></script>' and still will not get executed by the dom because of the insertion method innerHTML that is used to set it on the object.

scripts get executed on insert script insert don't get detected when directly setting the dom without dom API. That's how the dom parser works.

Sign up to request clarification or add additional context in comments.

Comments

0

Can't confirm this but I think you need to pass a React component instead of react element. That's why it won't work.

class reactScriptElement extends React.Component {
  ...
  componentWillMount() {
    const script = document.createElement("script");
    script.src = "d.js";
    document.body.appendChild(script);
  }
  ...
}

ReactDOM.render(reactScriptElement, document.getElementById('button'));

Usually React.createElement is used to return from render() method of a react component. Your way of creating element won't work because you're passing an element instead of component.

Correct usage of React.createElement()-

class App extends React.Component {
  ...
  render() {
    return React.createElement(MyLabel, {label: "Here is the label prop"},
      React.createElement("div", {},
        React.createElement("input", {type: "text", value: "And here is a child"})
      )
    );
  }
};

2 Comments

Nope, the render methods take an element, and not a component.. Don't confuse with the JSX syntex, as I am using vanila JS.
@DanielRahamim Ok. hope you find the answer. Good luck!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.