23
loading...
This website collects cookies to deliver better user experience
import React from 'react'
import Image, { ImageProps } from 'next/image'
type ImageWithStateProps = ImageProps
function ImageWithState (props: ImageWithStateProps) {
return <Image {...props} />
}
function ImageWithState (props: ImageWithStateProps) {
const [loading, setLoading] = React.useState(true)
const [onErrorSrc, setOnErrorSrc] = React.useState<string | undefined>(undefined)
return <Image {...props} />
}
loading
is set to true by default as the image would start loadingfallback
image. The fallback image appears when the Image component throws an error. Let's go ahead and create the function to handle the errored statefunction handleOnError (e: React.SyntheticEvent<HTMLImageElement, Event>): void {
e?.currentTarget?.src !== props.fallback && setOnErrorSrc(props.fallback)
}
return <Image {...props} onError={(e) => handleOnError(e)} />
src
prop of the element to the fallback image. return (
<div style={{ position: "relative" }}>
{loading === true && (
<SkeletonLoader
style={{
position: "absolute",
zIndex: props.debug === "true" ? 99 : "auto"
}}
height={props.height}
width={props.width}
/>
)}
<Image
{...props}
src={onErrorSrc || src}
onLoadingComplete={() => !props.debug && setLoading(false)}
onError={(e) => handleOnError(e)}
/>
</div>
);
debug
prop which can be helpful when developing & styling to check if the loading indicators are styled appropriately. height
and width
prop to the skeleton loader. This also further helps in avoiding layout shift as the space will be preserved for the image.type ImageWithStateProps = ImageProps & {
fallback: string;
debug?: string;
};
react-skeleton-loader
adds approximately 5kB to your production build. But keep in mind that this component is reusable across your entire app so the build size won't bloat up further placeholder
property on the Image component.unoptimized
true prop passed to the Image component. This is because I haven't setup any loader configuration for these images. Make sure to keep your images optimised and pass srcSet
, (now device sizes in Next.js) & responsive images in modern image formats!blurred
placeholder when an image is being loaded, something like what you may have seen on medium.com.