Consider following component
import React from 'react';
function Image() {
function onLoad() {
console.log("Loaded...")
}
return (
<img
src="http://..."
onLoad={onLoad}
decoding="async"
/>
);
}
export default Image;
For some reason onLoad
event isn't firing consistently i.e. when I initially load the page and refresh it it is not triggered, but when I mount component interactively in react i.e without page load it is triggered.
I played around with removing decoding="async"
and adding onError
handler to see if those gave more info, but behaviour didn't change.
I see this same behaviour on macOS safari and chrome browsers.
EDIT: In cases where it doesn't work image is not loaded at all
Consider following component
import React from 'react';
function Image() {
function onLoad() {
console.log("Loaded...")
}
return (
<img
src="http://..."
onLoad={onLoad}
decoding="async"
/>
);
}
export default Image;
For some reason onLoad
event isn't firing consistently i.e. when I initially load the page and refresh it it is not triggered, but when I mount component interactively in react i.e without page load it is triggered.
I played around with removing decoding="async"
and adding onError
handler to see if those gave more info, but behaviour didn't change.
I see this same behaviour on macOS safari and chrome browsers.
EDIT: In cases where it doesn't work image is not loaded at all
Share Improve this question edited Dec 3, 2019 at 8:29 Ilja asked Dec 2, 2019 at 16:58 IljaIlja 46.5k103 gold badges289 silver badges526 bronze badges 2- Does the image load without firing the onLoad event or does the image not load? – anna Commented Dec 2, 2019 at 17:04
- @anna not load at all – Ilja Commented Dec 3, 2019 at 8:28
4 Answers
Reset to default 18I figured out how to make it work in my case. I guess onLoad event wasn't executing because image was already loaded, so I altered my code to the following and it works as expected now
import React, { useRef, useEffect } from 'react';
function Image() {
const imgRef = useRef<HTMLImageElement>(null);
function onLoad() {
console.log("Loaded...")
}
useEffect(() => {
if (imgRef.current?.complete) {
onLoad();
}
}, []);
return (
<img
ref={imgRef}
src="http://..."
onLoad={onLoad}
decoding="async"
/>
);
}
export default Image;
Can you provide more info about the error? It should work, using an arrow function and calling it on the onLoad event of the img
import React from 'react';
onLoadFunction=()=>{
console.log('just loaded');
}
return (
<img
src="http://..."
onLoad={this.onLoadFunction}
/>
);
}
export default Image;
The issue might be that Image
is a reserved keyboard in DOM, Consider Changing name of the function. Otherwise it might change the Image Class.
// Image Size is >3MB
const App = () => {
const onImageLoad = () => {
console.log("Working...")
}
return (
<div>
<img src="https://unplash-api.herokuapp.com/api/Ri8c2qFg32A/full" onLoad={onImageLoad}/>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
img {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
The reason is because the image is loaded even before React hydrates the page and starts listening to the image's load
event. A more in-depth explanation can be found on this GitHub issue.
To solve this issue, @ilja's solution of checking if the image has already loaded via the .complete
attribute in a useEffect
works well.