[React] key로 컴포넌트 상태 초기화, 마운트 시켜야하는 경우

물음표살인마·2025년 6월 17일

트러블슈팅

목록 보기
2/2
post-thumbnail

문제상황

프로필 이미지를 설정할 수 있는 기능이 있다.
프로필 이미지가 없으면 에러 이미지를 보여주고 있으면 이미지가 노출된다.
프로필 이미지가 없는 상태에서 프로필 이미지를 설정했을 때 화면에 바로 반영이 안되는 문제가 발생했다.

	<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번 상황에서는

  • 초기에 src가 존재하기 때문에 img태그가 렌더링되고
  • src가 다른 값으로 변경되면 리렌더링 되면서
  • src가 다른 값으로 바뀌어
  • img태그에 바뀐 src가 들어가서 정상 작동된다.

2번 상황에서는

  • 초기에 src 가 존재하기 때문에 img태그가 렌더링 되었는데
  • src가 빈값이 되면서 onError가 발생한다.
  • 이때 isImageLoadingError가 true가 되어 에러 이미지가 노출된다.

3번 상황에서는

  • src가 초기에 없었기 때문에 img태그가 마운트되지 않았다.
  • 그래서 src가 다른 값으로 변경되어도
  • img태그가 없기 때문에 화면에 노출되지 않는다.

내 코드는 isImageLoadingError 값으로 분기를 치고 있었기 때문에
img태그가 화면에 렌더링 되지 않는 경우가 있어서 생긴 문제이고

만약에 errorImage 를 React.Node 타입으로 지정하지 않아도 된다면
아래처럼 img 태그 자체에 src에 분기를 치면 key값을 주지 않아도 된다.

	<img
			{...props}
			alt={alt}
            src={props.src || errorImage}
			onError={() => setIsImageLoadingError(true)}
		/>

key를 주면 key가 바뀔 시 해당 컴포넌트를 새로 마운트하기 때문에 내 문제가 해결되는 것이다.

profile
웹 프론트엔드 개발자

0개의 댓글