How To Pass a Ref to a SVG Component in React

Viewed 4477

I have a svg component that is declared like so:


import {ReactComponent as Icon} from 'someplace.svg'

function SomeComponent(props){
   const [someState, setSomeState] = useState(0)
   const iconRef = useRef(null)

   useEffect(() => {
      //always prints null
      console.log(iconRef.current) 
   }, [someState])

return <div>
 <button onClick={() => setSomeState(prev => prev + 1)}>{someState}</button>
 <Icon ref={iconRef}/>
</div>
}

The problem here is that iconRef will always return null. I think this is because it is declared as a component so the ref would need to be forwarded directly to the svg tags but how do I do that?

Any ideas?

1 Answers

This could be fixed in 3 steps:

  1. Get the SVG icon as a React Component in your codebase.
  2. Pass setRef to it.

Example:

Grab the SVG code into the component, like this:

const CloseIcon = (props) => (
  <svg
    width="38"
    height="38"
    viewBox="0 0 38 38"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <circle cx="19" cy="19" r="18" stroke="#AFAFAF" stroke-width="2"></circle>
    <path
      d="M13.0548 13.336L24.9868 25.9185"
      stroke="#AFAFAF"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"
    ></path>
    <path
      d="M24.9862 13.3365L13.0542 25.9189"
      stroke="#AFAFAF"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"
    ></path>
  </svg>
)

export default CloseIcon

Then, in the Parent Component, where you use this icon, set its ref property, like:


...

const closeIconRef = createRef()
...

<CloseIcon
   style={{ position: 'absolute', top: 18, right: 18, cursor: 'pointer' }} 
   setRef={closeIconRef}
/>

Then add setRef to the tag in your SVG component:

const CloseIcon = ({ setRef }) => (
  <svg
    ref={setRef}
    width="38"
    height="38"
    viewBox="0 0 38 38"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
...

You are done!

*The important thing to remember: the child nodes still are non-referenced, so it works if there are no shapes on the way of a hit. You can attach a ref to every child tho.

Related