So in my react app, I have a SVG container and I am attempting to append a tag (which has paths inside it) to it.
I am referring to the SVG container with a ref.
My code does the following:
let path1Black = createElement("path", {d: pathString, stroke: "black"});
let path2Black = createElement("path", { d: pathString, stroke: "black"});
let blackPathsArr= []; blackPathsArr.push(path1Black ); blackPathsArr.push(path2Black );
let blackPathGroup = createElement("g", { className: 'blackPG' }, blackPathsArr);
let path1Blue = createElement("path", {d: pathString, stroke: "blue"});
let path2Blue = createElement("path", { d: pathString, stroke: "blue"});
let bluePathsArr= []; bluePathsArr.push(path1Blue ); bluePathsArr.push(path2Blue );
let bluePathGroup = createElement("g", { className: 'bluePG' }, bluePathsArr);
let combinedPaths = [blackPathGroup, bluePathsGroup];
let finalGContainer = createElement("g", {}, combinedPaths );
//now finally attaching it to the ref
svgRef.current.appendChild(finalGContainer);
However when I do this, I am getting an error saying "Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'."
I don't understand. How is it not a node if the finalGContainer was succesfully created using the "createElement" function? I mean if it truly is not a node, then an error would have been generated there right?
So in my react app, I have a SVG container and I am attempting to append a tag (which has paths inside it) to it.
I am referring to the SVG container with a ref.
My code does the following:
let path1Black = createElement("path", {d: pathString, stroke: "black"});
let path2Black = createElement("path", { d: pathString, stroke: "black"});
let blackPathsArr= []; blackPathsArr.push(path1Black ); blackPathsArr.push(path2Black );
let blackPathGroup = createElement("g", { className: 'blackPG' }, blackPathsArr);
let path1Blue = createElement("path", {d: pathString, stroke: "blue"});
let path2Blue = createElement("path", { d: pathString, stroke: "blue"});
let bluePathsArr= []; bluePathsArr.push(path1Blue ); bluePathsArr.push(path2Blue );
let bluePathGroup = createElement("g", { className: 'bluePG' }, bluePathsArr);
let combinedPaths = [blackPathGroup, bluePathsGroup];
let finalGContainer = createElement("g", {}, combinedPaths );
//now finally attaching it to the ref
svgRef.current.appendChild(finalGContainer);
However when I do this, I am getting an error saying "Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'."
I don't understand. How is it not a node if the finalGContainer was succesfully created using the "createElement" function? I mean if it truly is not a node, then an error would have been generated there right?
Share Improve this question asked Mar 23 at 19:23 JackieChilesTheSecondJackieChilesTheSecond 1012 bronze badges 6- 3 React createElement does not do the same thing as document.createElement. – James Commented Mar 23 at 19:35
- @James , so how do I create a proper <g> node which I can append to the SVG container in React? – JackieChilesTheSecond Commented Mar 23 at 19:37
- 1 Are you creating a new svg or modifying an existing one? Need more context/code please. – James Commented Mar 23 at 20:05
- @James , I have only one SVG tag on my page that acts as the container (drawing board). This SVG tag has the ref "svgRef" and I have passed this ref to a child component. It is inside the child component where I am trying to create a <g> tag and append it to this container via its ref. – JackieChilesTheSecond Commented Mar 23 at 20:58
- 1 So if you need the above to be done "in javascript" instead of "in react", you can use document.createElement or document.createElementNS. You can get a reference to document from svgRef.current.ownerDocument. – James Commented Mar 23 at 21:43
1 Answer
Reset to default 1I don't understand. How is it not a node if the finalGContainer was succesfully created using the "createElement" function?
as pointed out in the comments previously, createElement
does not create a DOM node. When you console log finalGContainer
you'll see it's a Symbol instead of a <g>
SVG element
In order to append finalGContainer
as a child of the SVG, you have two options
- set the SVG as your root react element, then
root.render(finalGContainer)
- convert your react element(s) to DOM node(s) (also previously recommended) by:
- converting
finalGContainer
to a string of HTML - parsing that string of HTML into actual HTML
- then attaching the parsed HTML's first child ( which is finalGContainer) to your svg
- converting
const htmlStr = ReactDOMServer.renderToString(finalGContainer)
const domNode = new DOMParser().parseFromString(htmlStr, 'text/html').body.firstChild
svg.appendChild(domNode)