1

I'm trying to get the naturalWidth and naturalHeight from onLoadingComplete props: https://nextjs.org/docs/api-reference/next/image#onloadingcomplete but its not working? Perhaps I'm doing it wrong?

I have this function:

const handleImageLoad = (e) => {
  console.log("load", e);
};

then I have this component from next.js

<Image
  onLoadingComplete={(e) => handleImageLoad(e)}
  className=""
  src={image["data_url"]}
  alt=""
  layout="fill"
  objectFit="contain"
/>

When the image is loaded, it doesn't do anything, if I try to console log, it works, but I don't know why its not working when I'm passing the handleImageLoad

onLoadingComplete={() => handleImageLoad()}
hellomello
  • 8,219
  • 39
  • 151
  • 297
  • Can you please provide us a [MRE](https://stackoverflow.com/help/minimal-reproducible-example)? With your current description I am unable to reproduce the issue: https://codesandbox.io/s/loving-mahavira-9ygdi?file=/pages/layout-fill.js (Redirect to `/layout-fill` and scroll down to the second image to see logs.) – brc-dd Sep 24 '21 at 16:45
  • 1
    @brc-dd so I have a codesandbox where you can upload an image: https://codesandbox.io/s/proud-rain-d51sv?file=/pages/index.js, line 62-63 – hellomello Sep 24 '21 at 16:50
  • It appears that `onLoadingComplete` is not being triggered in case of data (base64) URI. Also that line 63 thing is seemingly working because it is being simply called on each component mount/render. `() => {console.log('loaded')}` should work, which isn't. I guess you need to create a issue/discussion for this on the Next.js' GitHub. A workaround can be to create blob:// URLs instead of data URI. I am not sure though if it will work or not. – brc-dd Sep 24 '21 at 17:09
  • 1
    Can confirm that it is working on object URLs (`blob:`). https://codesandbox.io/s/jolly-ellis-4htdl?file=/pages/index.js – brc-dd Sep 24 '21 at 17:31
  • @brc-dd can confirm as well. thanks! do you want to create an answer so I can accept it? – hellomello Sep 24 '21 at 18:16

1 Answers1

4

Edit: Fixed in v11.1.3-canary.33


It appears that the next/image component is not invoking onLoadingComplete handler in case provided src is a data URI. (And I can see you've opened an issue here for the same.)

For now a workaround can be to use Object URLs. If you wish, you can implement this quite directly. Refer this thread or the linked questions.

If you want to keep using react-images-uploading, you can use the methods mentioned in this thread and others, to convert the provided data URI to Object URL then pass it as src to next/image. Obviously, this will be more performance heavy operation that handling the uploaded file yourself.

Here is a working example: https://codesandbox.io/s/jolly-ellis-4htdl?file=/pages/index.js

Just adding an alternative for the sake of completeness:

import { useState } from "react";
import Image from "next/image";

const IndexPage = () => {
  const [src, setSrc] = useState("");

  const handleChange = (e) => {
    setSrc(URL.createObjectURL(e.target.files[0]));
    return true;
  };

  const handleImageLoad = (e) => {
    console.log("load", e);
  };

  return (
    <>
      <input
        type="file"
        id="foo"
        name="foo"
        accept="image/png, image/jpeg"
        onChange={handleChange}
      />
      <div
        style={{
          marginTop: "1rem",
          width: 600,
          height: 600,
          backgroundColor: "blue",
          position: "relative"
        }}
      >
        {src?.length > 0 && (
          <Image
            onLoadingComplete={(e) => {
              handleImageLoad(e);
            }}
            src={src}
            alt=""
            layout="fill"
            objectFit="contain"
          />
        )}
      </div>
    </>
  );
};

export default IndexPage;
brc-dd
  • 10,788
  • 3
  • 47
  • 67
  • Thank you so much! Curious.. do you know of any other package that I should look into for image uploading if `react-images-uploading` might not be the best due to this issue? – hellomello Sep 24 '21 at 18:43
  • 1
    @hellomello give a try to [`react-dropzone`](https://www.npmjs.com/package/react-dropzone). A demo here - https://react-dropzone.js.org/#section-previews – brc-dd Sep 24 '21 at 18:53
  • 1
    @hellomello A fix for this has been started by the Next.js team. After suitable test integrations it will be merged, and shall be there in the next patch release. – brc-dd Sep 24 '21 at 19:32
  • I saw! thank you! thanks for the suggestion to bring it up to the team! – hellomello Sep 24 '21 at 21:51
  • I am using NextJS v12.1.6 but still doesn't work, not merged yet? – Ander May 23 '22 at 08:18