Web/React

[React] 업로드한 사진 미리보기 구현

깨구르르 2024. 11. 21. 23:54
728x90

사진을 업로드 한 후, 사용자가 업로드한 사진이 화면에 바로 반영되는 기능을 구현해보았다.

아래는 파일 업로드 컴포넌트 코드이다.

tailwind css와 일반 css가 혼재되어 있어서 깔끔하지 않음 주의

import React, { useState } from "react";

const Profile_picture = ({ onchange }) => {
  const [imagePreview, setImagePreview] = useState(null);

  const handleImageChange = (event) => {
    const file = event.target.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onloadend = () => {
        setImagePreview(reader.result); // 파일을 읽어 들인 후 이미지 미리보기 상태 업데이트
      };
      reader.readAsDataURL(file);
    }
    if (onchange) {
      onchange(event);
    }
  };

  return (
    <div>
      <p>
        프로필 사진
      </p>
      <div className="flex justify-center items-center self-stretch flex-grow-0 flex-shrink-0 relative gap-2.5">
        <div className="flex-grow-0 flex-shrink-0 w-[100px] h-[100px] relative">
          {/* 파일 선택을 위한 input */}
          <input
            type="file"
            accept=".jpg, .jpeg, .png"
            onChange={handleImageChange} // 파일 선택 시 이미지 처리
            className="absolute top-0 left-0 w-[100px] h-[100px] opacity-0 cursor-pointer rounded-full z-10"
          />
          {/* 이미지 미리보기 */}
          <div
            className="w-[100px] h-[100px] rounded-full bg-[#D9D9D9] flex justify-center items-center"
            style={{
              backgroundImage: imagePreview ? `url(${imagePreview})` : "none",
              backgroundSize: "cover",
              backgroundPosition: "center",
            }}
          >
            {!imagePreview && (
              <img
                src="/image.png"
                className="w-[47px] h-[47px] object-none z-0"
              />
            )}
          </div>
          
        </div>
      </div>
    </div>
  );
};

export default Profile_picture;
  • imagePreview는 이미지 미리보기 URL을 저장하는 상태이다.
  • handleImageChange는 이미지가 바뀔 때 작동하는 핸들러 함수이다.
    • 사용자가 파일을 선택하면 event.target.files[0]로 첫 번째 파일을 가져온다.
    • FileReader 객체를 사용하여 파일 데이터를 읽어온다.
    • readAsDataURL 메서드는 파일을 Base64 형식으로 읽는다.
    • 파일 읽기가 완료되면 reader.onloadend 콜백이 실행되고, 읽어들인 데이터를 imagePreview 상태에 저장한다.
    • onChange prop이 전달되었다면, 이를 호출해 파일 선택 이벤트를 부모로 전달한다.
  • 파일 업로드 input
    • type을 file로 지정해 클릭 시 파일을 입력할 수 있게 하였다.
    • accept를 통해 지원 파일 확장자를 .jpg, .jpeg, .png로 제한하였다.
  • 이미지 미리보기
    • imagePreview 상태가 존재하면 해당 URL을 backgroundImage로 설정해 이미지를 표시한다.
    • 이미지가 없으면 기본 이미지인 image.png가 표시된다.

 

input 태그 내에는 파일 크기를 제한하는 게 딱히 없다고 한다.

파일 크기를 제한하려면 자바스크립트 코드를 추가해야 한다.

 

728x90