Skip to content

Instantly share code, notes, and snippets.

@jordymeow
Last active July 25, 2022 17:44
Show Gist options
  • Save jordymeow/ed083811e407e89b49c0eecd7f722695 to your computer and use it in GitHub Desktop.
Save jordymeow/ed083811e407e89b49c0eecd7f722695 to your computer and use it in GitHub Desktop.
Simple React Hook which handles the status (loading, loaded or failed) of your images. It does a bit of caching.
const { useState, useEffect, useRef } = require('react');
function useImage({ src }) {
let [ image, setImage ] = useState({ src: null, status: 'loading' });
let imageElement = useRef();
let loadedUrls = useRef(new Set());
useEffect(() => {
const onload = () => {
setImage(img => {
loadedUrls.current.add(img.src);
return { ...img, status: 'loaded' };
});
};
const onerror = () => { setImage(img => ({...img, status: 'failed'})) };
imageElement.current = document.createElement('img');
imageElement.current.addEventListener('load', onload);
imageElement.current.addEventListener('error', onerror);
return function cleanup() {
imageElement.current.removeEventListener('load', onload);
imageElement.current.removeEventListener('error', onerror);
};
}, []);
useEffect(() => {
if (!src || loadedUrls.current.has(src)) {
// No image, or already loaded.
setImage({ src: src, status: 'loaded' });
}
else {
// New image to load.
imageElement.current.src = src;
setImage({ src: src, status: 'loading' });
}
}, [src]);
return {
src: image.src,
isLoading: image.status === 'loading',
isLoaded: image.status === 'loaded',
hasFailed: image.status === 'failed'
};
};
export default useImage;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment