Recently, I had a requirement to create lines using SVG for my home page design. I couldn't hard code all the SVG line elements in my JSX since the number of lines were dynamic and I needed to do some positioning logic as well.
Failed code
So I ended up with a simple useEffect
code that runs once after everything renders and append the SVG lines.
useEffect( () => {
const svgElm = document.querySelector("#svgHolder");
const lineElm = document.createElement("line");
lineElm.setAttribute("x1", "20");
// ... set other attributes
svgElm.appendChild(lineElm);
}, []); // run once
The above code added the line
tags to the svg
element. However, it did not render anything at all on screen. The nodes were present in DOM, but nothing shows up on screen.
document.createElementNS
It turns out I need to create the line
element under a specified name space using the DOM API document.craateElementNS
. SO once I change document.createElement
with document.createElementNS
and the right namespace, my SVGs were rendering properly.
useEffect(() => {
const svgElm = document.querySelector("#svgHolder");
/* use proper namespace to create line element */
const lineElm = document.createElementNS(
"http://www.w3.org/2000/svg",
"line",
);
lineElm.setAttribute("x1", "20");
svgElm.appendChild(lineElm);
}, []);