next.js: Image Component doesn't forwardsRef
Bug report
Describe the bug
Refs aren’t properly supported in Image.
import React, { useState, useCallback } from 'react'
import Image from 'next/image'
const NextImage = ({ src }) => {
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
const ref = useCallback((node) => {
console.log(node)
}, [])
return <Image ref={ref} src={src} width={width} height={height} />
}
This code shows that Image does not forwardRef to img DOM element.
To Reproduce
- Add Image component to your page
- Add ref via
useCallback
hook - Try to do something within callback function
Expected behavior
Image component should pass ref function to img element.
System information
- OS: macOS
- Browser (if applies) [Chrome, Safari]
- Version of Next.js: 10.0.0
- Version of Node.js: 15.0.0
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 55
- Comments: 33 (11 by maintainers)
Commits related to this issue
- Add `onLoadingComplete()` prop to Image component (#26824) This adds a new prop, `onLoadingComplete()`, to handle the most common use case of `ref`. I also added docs and a warning when using `ref` ... — committed to vercel/next.js by styfle 3 years ago
- Add example notion (#1) * [WIP] Add cms notion integration example - index page * Add cover images for pages * Add post page * Remove preview functionality * Add module.exports to securit... — committed to leimonio/next.js by leimonio 3 years ago
- Add `onLoadingComplete()` prop to Image component (#26824) This adds a new prop, `onLoadingComplete()`, to handle the most common use case of `ref`. I also added docs and a warning when using `ref` ... — committed to blitz-js/next.js by styfle 3 years ago
- Fix `style.filter` on image with `placeholder=blur` (#32623) Fixes https://github.com/vercel/next.js/issues/18398#issuecomment-995871025 — committed to vercel/next.js by styfle 3 years ago
- Fix style reset on image with `placeholder=blur` (#32680) This PR is a follow up to PR #32623 to fix the remaining blur styles. These are unlikely to be overridden by the user but this PR is necessa... — committed to vercel/next.js by styfle 3 years ago
- Fix `style.filter` on image with `placeholder=blur` (#32623) Fixes https://github.com/vercel/next.js/issues/18398#issuecomment-995871025 — committed to natew/next.js by styfle 3 years ago
- Update `onLoadingComplete` for `next/future/image` to receive reference to `<img>` (#40326) * fixes #18398 * fixes #38864 Co-authored-by: Steven <steven@ceriously.com> — committed to vercel/next.js by cvbuelow 2 years ago
- Add `ref` forwarding for `next/image` (#43193) Add ref forwarding for next/image with integration test - fixes https://github.com/vercel/next.js/discussions/42885 - fixes https://github.com/vercel/... — committed to jimCresswell/next.js by jankaifer 2 years ago
For extra context, the
Image
component exposes anonLoad
event but addingonLoad
does not reliably work for server side rendered images, the solution is checkingimg.complete
on the ref instead. Not having a ref for the Image component prevents us from doing that kind of check for cases like rendering a skeleton while an image is loading.Hi everyone, thanks for the feedback!
I read through all the comments here and it seems the majority use cases for
ref
could be solved by adding a new proponLoadingComplete()
.Does that sounds like a good solution? 👍 or 👎
Echoing @Xetera, a reliable way to detect the load state of an image is required in order to animate its entrance with
react-spring
, so I would expect access to theimg
element.@Timer I would also love for this to forward refs, there are many reasons why this is important, as listed above. The ref should go to the underlying
img
tag in my mind.Thanks!
+1 on wanting to pass ref down to to be able to access “imgRef.current.complete”.
I want to use the next/image component for the Automatic Image Optimization, but I want to trigger an animation when the image is loaded.
Does anyone have a suggestion about workaround in the meantime?
My use case: query image natural size, animate it using DOM API.
Other use cases already mentioned by others:
We are currently using ‘react-content-loader’ as our skeleton/animation lib, and this is how we handled not having access to the next image ref.
We are basically setting the image as
imgLoaded
, when it’s not hidden anymore (by the visibility property in the element’s style attribute). It was the best we could came up, at least in terms of syncing when the image was ready to be showed to the user and removing the loader.I would expect it to go to the component similarly to all other props not referenced by next/image.
My use case is wanting to programatically determine if the image has loaded yet, and toggle a className based on that.
I also support being able to forward a ref to the root image element. In my case I need it for a feature I am building out with framer-motion and need access to the image’s complete property.
I’ve opened up PR #22482 that should address this issue.
I would also prefer the
ref
approach, my use case is doing animations that will require me to have access to the image element. I’m not sure what the implications of adding the option to forwardRef’s would be, as I’ve not looked into how theImage
component works exactly, but it would be nice to have that option enabled for whoever wants to use it.We released
onLoadingComplete()
today in next@11.0.2-canary.4.Try it out now with
yarn add next@canary
, thanks!@pffigueiredo There is also a different solution to knowing when the image is loaded. You can avoid looking for the 1x1 gif file so the onLoad event is only fired on the actual image.
How would one go about using any kind of animation library (say framer motion in my case) with the Image component if framer can’t attach it’s ref onto the container?
There should be affordance to add a user defined ref on the image as well as the container div.
Also currently I don’t think this component is usable with framer even if ref is added because the layout prop collides with framer motion’s layout prop.
My use-case is adding a link to the image, the
Link
passes ref to it’s child component.@luigi-derson This looks like a bug, no need for
ref
.This will be fixed in PR #32623, thanks!
You do not need a ref for this behavior. The Image component already works like this with its intrinsic behavior.