gilbarbara / react-inlinesvg

An SVG loader component for ReactJS
https://codesandbox.io/s/github/gilbarbara/react-inlinesvg/tree/main/demo
MIT License
1.27k stars 100 forks source link

innerRef is always null unless you make changes in code and the page gets hot module updated #215

Closed milaabl closed 1 year ago

milaabl commented 1 year ago

Describe the bug

The ref.current object is always null on the first load, unless you change something in the code.

You can see it yourself in the Console on Codesandbox here: https://codesandbox.io/s/silly-williams-tysf4l?file=/src/App.tsx

I have the same issue in my code, but I think just the reproduction above might be sufficient to showcase the bug.

import * as React from "react";
import SVG from "react-inlinesvg";

const { env } = process;

env.PUBLIC_URL = env.PUBLIC_URL ?? "";

export default function App() {
  const ref = React.useRef<SVGElement>(null);

  React.useEffect(() => {
    console.log(ref);
  }, [ref.current]);

  return <SVG innerRef={ref} src={`${process.env.PUBLIC_URL}/vue.svg`} />;
}

image

Your minimal, reproducible example

https://codesandbox.io/s/silly-williams-tysf4l?file=/src/App.tsx

Steps to reproduce

  1. Go to https://codesandbox.io/s/silly-williams-tysf4l?file=/src/App.tsx
  2. Open the console & see the issue

Expected behavior

There should be the reference to the SVG element in the DOM instead of a null value.

How often does this bug happen?

Every time

Screenshots or Videos

image

Platform

Browser: Chrome

react-inlinesvg version

4.0.3

TypeScript version

5.0.2

Build tool

Webpack, Vite, create-react-app — all of these

Additional context

No response

milaabl commented 1 year ago

@gilbarbara, I'd be so grateful if you can help me figure out the bug! Please take a look at the repro.

gilbarbara commented 1 year ago

Hey @milaabl

The SVG is processed and parsed so that the ref won't be available after the first render. You can use the onLoad callback to get and use the ref instead.

milaabl commented 1 year ago

@gilbarbara, thank you so much for replying to me quickly!

The solution you suggested doesn't work though. https://codesandbox.io/s/silly-williams-tysf4l?file=/src/App.tsx. Please take a look at it!

I thought that if you pass a reference, the react-inlinesvg component should populate it w/ the reference of the SVG element from the DOM.

It doesn't have to be on the first load or immediately, but it should finally be there.

Though I see that ref.current never gets a value other than null.

milaabl commented 1 year ago

If the ref never gets a DOM value by passing it as the innerRef={ref} prop, then what's the purpose of the innerRef prop? Please let me know.

gilbarbara commented 1 year ago

The parameters for the onLoad callback are src and isCached. There's no ref. Instead, just set a handler and use your own ref inside it.

onLoad={() => {
  console.log(ref.current);
}}
milaabl commented 1 year ago

@gilbarbara, thank you so much for suggesting the solution! It works for me now. 🙏

Have a great day!