Skip to content

Instantly share code, notes, and snippets.

@RenaudRohlinger
Last active March 15, 2021 06:40
Show Gist options
  • Save RenaudRohlinger/9ddbb6769cbbf31a0e11e7460b70522c to your computer and use it in GitHub Desktop.
Save RenaudRohlinger/9ddbb6769cbbf31a0e11e7460b70522c to your computer and use it in GitHub Desktop.
Preload Images with React
import React, { FC, useEffect } from 'react';
type State = {
progress: number;
isLoading: boolean;
}
const useStore = create<State>((set, get) => ({
isLoading: true,
progress: 0,
}
// the helper
const cacheImages = async srcArray => {
let progress = 0;
const promises = await srcArray.map((src: string) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = _ => {
progress++;
useStore.setState({
progress: Math.round((progress / srcArray.length) * 100),
});
resolve(img)
};
img.onerror = _ => {
reject();
};
});
});
await Promise.all(promises);
progress = 100;
useStore.setState({ isLoading: false, progress: 100 });
};
const Progress: FC = () => {
const loadingProgress = useStore(state => state.loadingProgress);
return <h1>{loadingProgress}</h1>;
};
// use it like this
export const Loader: FC = () => {
const isLoading = useStore(state => state.isLoading);
useEffect(() => {
const imgs = ['/images/a.jpg', '/images/b.jpg', ...];
cacheImages(imgs);
}, []);
return (
isLoading && (
<div>
⌛ <Progress />
</div>
)
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment