프로필 이미지를 설정할 수 있는 기능이 있다.
프로필 이미지가 없으면 에러 이미지를 보여주고 있으면 이미지가 노출된다.
프로필 이미지가 없는 상태에서 프로필 이미지를 설정했을 때 화면에 바로 반영이 안되는 문제가 발생했다.
<Image
alt="store-thumbnail"
src={imageUrl}
errorImage={<EmptyStoreImage />}
/>
import type { FC, ImgHTMLAttributes, ReactNode } from 'react';
import { useState } from 'react';
interface ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
errorImage: ReactNode;
}
const Image: FC<ImageProps> = ({ errorImage, alt = '', ...props }) => {
const [isImageLoadingError, setIsImageLoadingError] = useState(!props.src);
return !isImageLoadingError ? (
<img
{...props}
alt={alt}
onError={() => setIsImageLoadingError(true)}
/>
) : (
<>{errorImage}</>
);
};
export default Image;
이미지를 노출시키는 코드는 위 코드이다.
내가 직면한 문제는
1) props.src가 존재했을 때 -> 다른 값으로 변경되었 때
2) props.src가 존재하다가 -> 빈 값으로 변경되었을 때
3) props.src가 빈값이없다가 -> 다른 값으로 변경되었을 때
세 가지 경우에서 3번 경우에서만 화면 반영이 안되고 계속 errorImage가 노출되는 것이었다.
Image 태그에 key값을 주니까 정상 작동이 되었다.
<Image
key={imageUrl || 'empty'}
alt="store-thumbnail"
src={imageUrl}
errorImage={<EmptyStoreImage />}
/>
그런데 왜 key값을 주었을 때 정상적으로 작동했는지 알아보자.
props가 바뀌면 컴포넌트가 리렌더링 된다. 하지만 마운트되지는 않는다.
1번 상황에서는
2번 상황에서는
3번 상황에서는
내 코드는 isImageLoadingError 값으로 분기를 치고 있었기 때문에
img태그가 화면에 렌더링 되지 않는 경우가 있어서 생긴 문제이고
만약에 errorImage 를 React.Node 타입으로 지정하지 않아도 된다면
아래처럼 img 태그 자체에 src에 분기를 치면 key값을 주지 않아도 된다.
<img
{...props}
alt={alt}
src={props.src || errorImage}
onError={() => setIsImageLoadingError(true)}
/>
key를 주면 key가 바뀔 시 해당 컴포넌트를 새로 마운트하기 때문에 내 문제가 해결되는 것이다.