[React Native] 이미지 로딩 전에 placeholder 표시하기

aborile·2023년 5월 26일
0

React Native

목록 보기
5/8
post-thumbnail

현재 프로젝트에서는 빠른 이미지 로딩과 캐싱, 그리고 안드로이드 고화질 이미지 로딩을 위해 react-native-fast-image 라이브러리를 사용 중이다.

해당 라이브러리의 이름에서부터 알 수 있듯이 빠른 이미지 로딩을 지원한다고는 하지만, 이미지의 용량이 크거나 인터넷이 약간 느린 경우 약간의 깜빡거림이 어쩔 수 없이 존재하기는 하다. 때문에 모든 이미지의 로딩 전에 해당 이미지가 로딩 중이라는 자리를 표시할 수 있는 일종의 skeleton 역할의 placeholder를 표시하도록 공통 컴포넌트를 작성하였다.

import React, { memo, useEffect, useState } from "react";
import { StyleSheet, View } from "react-native";

import FastImage, { FastImageProps } from "react-native-fast-image";

interface ImageLoaderProps extends FastImageProps {
  height?: string | number;
  width?: string | number;
  useLoadingIndicator?: boolean;
  loadingIndicatorHeight?: string | number;
  loadingColor?: string;
}

/**
 * FastImage 라이브러리를 사용하되 image placeholder를 구현하기 위해 분리한 컴포넌트.
 * param으로 FastImageProps를 그대로 사용.
 */
const ImageLoader: React.FC<ImageLoaderProps> = ({
  onLoadEnd,
  loadingColor = "#DDDDDD",
  source,
  style,
  ...props
}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [image, setImage] = useState(source);

  useEffect(() => {
    setImage(source);
  }, [source]);

  return (
    <FastImage
      {...props}
	  style={style}
      source={image}
      onLoadEnd={() => {
        if (onLoadEnd) onLoadEnd();
        setIsLoaded(true);
      }}
    >
      {!isLoaded &&
        <View style={[style, styles.defaultLoader, { backgroundColor: loadingColor }]} />
      }
    </FastImage>
  );
};

export default memo(ImageLoader);

const styles = StyleSheet.create({
  defaultLoader: { width: "200%", height: "200%", marginTop: "-50%", marginLeft: "-50%" },
});

onLoadEnd prop을 통해 이미지의 로딩이 완료되는 시점을 캐치해서, 해당 시점 이전까지는 FastImage의 children으로 특정 색을 표시하도록 작성하였다.

단, 이 경우 로컬에 존재하는 이미지와 같이 아주 빠르게 로딩이 되는 이미지를 표시할 때에도 부자연스러운 깜빡거림이 생긴다는 단점이 있어, 필요 시에는 loadingColor="transparent"를 넘겨 깜빡거리지 않도록 사용하고 있다.

profile
기록하고 싶은 것을 기록하는 저장소

0개의 댓글