Skip to content

Commit

Permalink
feature: LazyImage 로딩, 에러 UI 설정 및 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
steveflevc committed Dec 31, 2024
1 parent 8a9740d commit d072ee7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/app/movie/components/movie-item.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import { LazyImage } from '@/components/lazy-image';

const MovieItem = ({ imageUrl }: { imageUrl: string }) => {
return (
<div className="w-full h-full aspect-video rounded-lg overflow-hidden cursor-pointer transition duration-300 ease-in-out hover:brightness-75">
<img
<LazyImage
className="w-full h-full"
alt={'movie'}
src={`https://image.tmdb.org/t/p/w300/${imageUrl}`}
Expand Down
30 changes: 27 additions & 3 deletions src/components/lazy-image.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import { useInView } from '@/hooks/use-in-view';

type ImageProps = Omit<React.ImgHTMLAttributes<HTMLImageElement>, 'alt'> & {
alt: string;
};

const LazyImage = ({ alt, src, srcSet, ...props }: ImageProps) => {
const LazyImage = ({ alt, src, srcSet, className, ...props }: ImageProps) => {
const imageRef = useRef<HTMLImageElement>(null);
const [isImageLoad, setIsImageLoad] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);

const handleIntersectImage = () => {
const $img = imageRef.current;
Expand All @@ -31,7 +33,29 @@ const LazyImage = ({ alt, src, srcSet, ...props }: ImageProps) => {
imageRef.current = $img;
};

return <img ref={handleSetRef} alt={alt} data-src={src} data-srcset={srcSet} {...props} />;
const handleImageLoad = () => {
setIsImageLoad(true);
};
const handleImageError = () => {
setIsError(true);
};

return (
<div className={`w-full h-full ${className}`}>
{!isImageLoad && !isError && <div className="w-full h-full bg-gray-300 animate-pulse" />}
{isError && <div className="w-full h-full bg-gray-300 flex items-center justify-center text-gray-500">Error</div>}
<img
ref={handleSetRef}
className={`w-full h-full transition-opacity duration-300 ${isImageLoad ? 'opacity-100' : 'opacity-0'}`}
onLoad={handleImageLoad}
onError={handleImageError}
alt={alt}
data-src={src}
data-srcset={srcSet}
{...props}
/>
</div>
);
};

export { LazyImage };

0 comments on commit d072ee7

Please sign in to comment.