Closed
Description
<script>
is a bit hard to use right now.
- If you have a
{...}
then it's going to start interpolating. And you are bound to have whenever you useif
,function
... Workaround: you can wrap it inside of an interpolated string{'if (true) { ... }'}
- If you have any
'
or"
it's going to output the html encoded version and Javascript is going to throw a parsing exception.
In order to workaround those two issues the best way I found is to use dangerouslySetInnerHTML and use ES6 backtick in order to have multi-line strings.
<script dangerouslySetInnerHTML={{__html: `
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('send', 'pageview');
`}} />
We should probably make it easier, it's quite a pain to use right now.
Activity
sophiebits commentedon Dec 11, 2013
What should it even mean to include a
<script>
tag? If you change the contents, does it get rerun? This seems fairly react-page-specific.vjeux commentedon Dec 11, 2013
Yeah, i'm not really sure that it is really useful in a normal React app but for react-page it's definitively useful. @zpao suggested that we change the
<script>
tag to behave like in the DOM. It takes a single string child that is not escaped like we do for spanssyranide commentedon Dec 27, 2013
@vjeux @zpao
I could look into fixing this... from what I understand, what needs to be done is to create a
ReactDOMScript
-component that should have aninvariant
that checks that it's either empty or has only 1 string as child (or possibly many strings?) and of course works like it should.What should happen if the string changes? Simply update the
script
-element and defer to the browser (I'm assuming they all do nothing) or recreate thescript
-element?Seems about right?
sophiebits commentedon Dec 27, 2013
We're getting rid of full-page rendering anyway (see #515, #585). I don't think it's worth doing anything special here.
syranide commentedon Dec 27, 2013
@spicyj It stills seems like being able to render into
body
will be supported, and evenhead
. Even if only rendering intobody
was supported, this could still be useful. But yeah, perhaps not worth the extra bytes.matthewwithanm commentedon Mar 12, 2014
Just ran into this. IMO, it's very surprising behavior that adding a
<script>
to your virtual dom doesn't result in the script's evaluation (asappendChild
would, for example). I created this fiddle to demonstrate the issue but, based on this thread, it seems like this is expected/desired?sophiebits commentedon Mar 12, 2014
@matthewwithanm Can you say a little more about your use case? I think we'd like to do the least surprising thing here but it's hard to know what that is; my guess is any behavior we have would be surprising in some way.
marten commentedon Aug 26, 2014
@spicyj If I may answer for @matthewwithanm, since I just ran into the same issue, we still have some server-side rendered pages that we would like to open inside a modal dialog.
I made a Dialog component that gets a URL via props, and on componentDidMount fetches HTML from the server, and renders it inside the dialog using dangerouslySetInnerHTML. I was quite surprised when I found out that the code inside the
script
tag that was also in the fetched HTML was not executed.syranide commentedon Aug 27, 2014
@marten
dangerouslySetInnerHTML
is just another name forinnerHTML
exposed by browsers, they do not execute<script>
when usinginnerHTML
. I believe jQuery has code that explicitly goes in and evals code inside<script>
, if that's what you were expecting.marten commentedon Aug 27, 2014
@syranide I guess I was just spoiled by jQuery and never realized that. I've already implemented this same behaviour myself, and it's for a layer that should be converted to actual React components anyway, so the workaround should disappear from our code at some point. It's not a big deal, just surprised me, but I guess it's just a lack of knowledge on my part.
bchenSyd commentedon Jun 1, 2017
@syranide thanks for sharing that! i didn't know it before