🖥️Frontend/React

[React] 이미지 파일 미리보기

뉴발자 2025. 5. 20. 19:13
728x90

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

개요

사용자가 이미지 파일을 업로드했을 때 해당 이미지를 미리보기 할 수 있도록 하는 기능을 구현하려고 한다.

 

 

파일 업로드

이미지 파일을 업로드 후 미리보기로 보여주는 페이지를 작성해준다.

 

업로드한 File 객체를 저장할 상태를 useState()를 사용해서 생성해준다.

그리고 파일을 업로드할 수 있게 type이 file인 input 태그를 만들어준다.

const Previewer = () => {
  // 사용자가 업로드한 파일을 저장할 상태
  const [ imageFile, setImageFile ] = useState<File>();
  
  return (
    <div>
      {/** 이미지 파일 업로드 버튼 */}
      <input 
        type="file"
        accept="image/*"
      />
    </div>
  );
};

export default Previewer;

 

파일 업로드 시 onChange 핸들러를 사용해서 파일 값을 상태에 저장시켜준다.

 

이때 setImageFile에 파일 객체를 바로 넣어주면 에러가 발생할 수 있으므로 따로 함수를 만들어준 뒤 넣어준다.

 

setImageFile을 사용해서 사용자가 업로드한 이미지 파일 객체를 저장해준다.

const Previewer = () => {
  const [ imageFile, setImageFile ] = useState<File>();
  const [ imageSource, setImageSource ] = useState("");

  // 이미지 파일을 상태에 넣어주는 함수
  const onChangeImageFile = (e: ChangeEvent<HTMLInputElement> | any) => {
    setImageFile(e.target.files[0]);
  };
  
  return (
    <div>
      <input 
        type="file"
        accept="image/*"
        onChange={(e) => onChangeImageFile(e)}
      />
    </div>
  );
};

export default Previewer;

 

 

이미지 미리보기

다음으로 이미지의 경로를 저장해줄 상태를 생성하고 이미지 태그를 만들어 준다.

const Previewer = () => {
  const [ imageFile, setImageFile ] = useState<File>();
  // 이미지 경로를 저장해줄 상태
  const [ imageSource, setImageSource ] = useState("");

  const onChangeImageFile = (e: ChangeEvent<HTMLInputElement> | any) => {
    setImageFile(e.target.files[0]);
  };
  
  return (
    <div>
      <input 
        type="file"
        accept="image/*"
        onChange={(e) => onChangeImageFile(e)}
      />
      {/** 미리보기 이미지 */}
      <img 
        alt="미리보기 이미지"
        src={imageSource}
        width={300}
        height={300}
      />
    </div>
  );
};

export default Previewer;

 

이미지 파일 업로드 시 파일을 읽은 후 파일의 경로를 setImageSource 에 넣어주는 함수를 작성해준다.

const Previewer = () => {
  const [ imageFile, setImageFile ] = useState<File>();
  const [ imageSource, setImageSource ] = useState("");

  const onChangeImageFile = (e: ChangeEvent<HTMLInputElement> | any) => {
    setImageFile(e.target.files[0]);
  };
  
  const onChangeImageSource = () => {
    if (imageFile) {
      // FileReader 객체 생성
      const fileReader = new FileReader();
  
      // Blob -> base64 데이터 변환
      fileReader.readAsDataURL(imageFile);
  
      // 파일 읽기 완료 시 실행되는 핸들러
      fileReader.onload = (e: any) => {
        setImageSource(e.target.result);
      };
    }
  };
  
  return (
    <div>
      <input 
        type="file"
        accept="image/*"
        onChange={(e) => onChangeImageFile(e)}
      />
      <img 
        alt="미리보기 이미지"
        src={imageSource}
        width={300}
        height={300}
      />
    </div>
  );
};

export default Previewer;

 

그리고 imageFile이 변경될 때마다 imageSource를 변경할 수 있도록 useEffect를 사용해서 작성해준다.

const Previewer = () => {
  const [ imageFile, setImageFile ] = useState<File>();
  const [ imageSource, setImageSource ] = useState("");

  const onChangeImageFile = (e: ChangeEvent<HTMLInputElement> | any) => {
    setImageFile(e.target.files[0]);
  };
  
  const onChangeImageSource = () => {
    if (imageFile) {
      // FileReader 객체 생성
      const fileReader = new FileReader();
  
      // Blob -> base64 데이터 변환
      fileReader.readAsDataURL(imageFile);
  
      // 파일 읽기 완료 시 실행되는 핸들러
      fileReader.onload = (e: any) => {
        setImageSource(e.target.result);
      };
    }
  };
  
  /** 이미지 파일이 변경될 때마다 실행되는 함수 */
  useEffect(() => {
    if (imageFile) {
      onChangeImageSource();
    }
  }, [imageFile]);
  
  return (
    <div>
      <input 
        type="file"
        accept="image/*"
        onChange={(e) => onChangeImageFile(e)}
      />
      <img 
        alt="미리보기 이미지"
        src={imageSource}
        width={300}
        height={300}
      />
    </div>
  );
};

export default Previewer;

 

 

결과

 

 

 

 

 

 

 

 

 

 

728x90