Question:
Can I render an SVGSVGElement
in React without using dangerouslySetInnerHtml
?
Context:
I am using the vis.js graph library, the getLegend
method returns an SVGSVGElement
object i.e.
const icon = chart.getLegend(args);
In the console I can see this:
in: icon instanceof SVGSVGElement
out: true
in: icon
out: <svg><rect x="0" y="0" width="30" height="30" class="vis-outline"></rect><path class="vis-graph-group0" d="M0,15 L30,15"></path></svg>
Problem:
When I try to render this in react using:
render (
<div> { icon } </div>
)
I get the following error:
Error: Objects are not valid as a React child (found: [object SVGSVGElement]). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `LegendElement`
Workaround:
For now I am using:
<svg dangerouslySetInnerHTML={{__html: icon.innerHTML}} />
But I was hoping for a straightforward solution that doesn't use a method with the word dangerous in the name.
Research:
I read this similar question but I don't think it helps for SVG generated at run time: How do I use an SVG in React without using dangerouslySetInnerHTML?
You can simple append the SVGSVGElement using a useRef like this. This example is for a functional component with hooks but can be adapted for class components.
const svg = useRef(null);
useEffect(()=>{
if(svg.current){
svg.current.appendChild(icon)
}
}, []);
return (
<div ref={svg}/>
);