Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React fails to render SVG children in Edge/IE #5061

Closed
dallonf opened this issue Oct 6, 2015 · 13 comments
Closed

React fails to render SVG children in Edge/IE #5061

dallonf opened this issue Oct 6, 2015 · 13 comments
Labels

Comments

@dallonf
Copy link

dallonf commented Oct 6, 2015

Here's a gist that illustrates the issue.

index.html will work as expected (rendering a red circle) in most browsers. If you run the phantom-run.js script in PhantomJS 2.0 (assuming you have the page hosted at localhost:3000), however, it throws this error:

Error: Invariant Violation: findComponentRoot(..., .0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.

and fails to insert the circle.

@sophiebits sophiebits added the SVG label Oct 7, 2015
@dallonf dallonf changed the title React fails to render SVG children in PhantomJS React fails to render SVG children in Microsoft Edge Oct 16, 2015
@dallonf
Copy link
Author

dallonf commented Oct 16, 2015

Update: I've just seen these symptoms in Microsoft Edge as well, which makes it much more serious. I'll be back in a bit with more research...

@dallonf dallonf changed the title React fails to render SVG children in Microsoft Edge React fails to render SVG children in Edge/IE Oct 16, 2015
@dallonf
Copy link
Author

dallonf commented Oct 16, 2015

Confirmed: the same problem affects Edge, IE (tested 11-9), and PhantomJS 2.0.

React 0.13 and earlier has the same problem, but does not report any error.

It is possible to add an SVG element using vanilla DOM methods in these browsers, e.g.:

var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("fill", "red");
circle.setAttribute("r", 50);
circle.setAttribute("cx", 50);
circle.setAttribute("cy", 50);
document.getElementById("gElement").appendChild(circle);

@dallonf
Copy link
Author

dallonf commented Oct 19, 2015

My theory as to what's going on here is that SVG elements do not support the innerHTML property consistently in browsers. A suitable workaround in most cases (since this is a really weird thing that probably doesn't need to be and isn't going to be fixed anytime soon) is to render the SVG element entirely in React (i.e. ReactDOM.render(<svg><circle /></svg>, document.getElementById('someDiv')) rather than ReactDOM.render(<circle />, document.getElementById('someSvg'))).

@islemaster
Copy link

👍 I am also having this issue, trying to use React to render an SVGGElement into an <svg> tag that isn't rendered by React. Unfortunately I have a very specific situation that makes it problematic for React to render the <svg> element, so the mentioned workaround isn't helping.

@zpao
Copy link
Member

zpao commented Nov 12, 2015

We're moving towards the use of createElement which would sidestep the issue of innerHTML. In the meantime I don't think there is much we can do here, sorry :(

If you wanted to get fancy you could do something hacky that updates your svg but otherwise renders into something else… in theory something like this (caveat that I haven't run it nor will I support it):

function renderReactIntoSVG(element, node) {
  var mynode = document.createElement('div');
  ReactDOM.render(<SVGReparenter into={node}>{element}</SVGReparenter>, mynode);
}

SVGReparenter = React.createClass({
  reparent: function() {
    // assume you only have a single child node which would map up to
    // expectations if you're subbing this code in for a React.render().
    this.props.into.replaceChild(
      this.props.into.firstChild,
      this.refs.root.firstChild.cloneNode(true)
    );
  }
  componentDidUpdate: function() {
    this.reparent();
  },
  componentDidMount: function() {
    this.reparent();
  },
  componentWillUnmount: function() {
    // cleanup after ourselves
    this.props.into.removeChild(this.props.into.firstChild);
  }
  render: function() {
    // TODO: maybe use callback refs
    return <svg ref="root">{this.props.children}</svg>
  }
})

@syranide
Copy link
Contributor

@zpao Could this be related to #2340? createNodesFromMarkup should take care of creating SVG-elements inside the right namespace (mostly at least).

@zpao
Copy link
Member

zpao commented Nov 13, 2015

Yea, that would solve this too (that's effectively effectively what I wrote above 😁). But I do think we'll be moving away from innerHTML, hopefully before next release.

@jkillian
Copy link

👍 Any updates on this? I as well can't use ReactDOM.render inside an SVG in IE. The SVG is pre-existing, so I can't render the entire thing with React either.

@jimfb
Copy link
Contributor

jimfb commented Feb 22, 2016

I think it works in master/future. http://jsfiddle.net/zcotr9hm/

If I'm wrong, let me know and we can re-investigate.

@jimfb jimfb closed this as completed Feb 22, 2016
@jkillian
Copy link

Thanks @jimfb, it seems to me that it's not fixed in latest (0.14.7) but is fixed in future/next (0.15.0-alpha.1). Glad to know that this should be resolved in a stable release soon!

@pnkapadia6
Copy link

@jimfb @zpao I have react 15.3.0 and svg issue is still happening in IE 11

@freakaziod210
Copy link

freakaziod210 commented Aug 23, 2017

Yeah. I think that I am seeing the same problem. React 15.6.1 on IE 11 and Edge

Update: Nevermind. What I am seeing is a bug with Edge and IE 11
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3723601/

@pervezalam83
Copy link

In my case Microsoft Edge 44.19041.423.0, does not support spread operator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants