input에 사진을 추가하고 preview를 함 봐볼까~~?

이수민(React_9기)·2025년 2월 13일
post-thumbnail

📸 이미지 미리보기 기능 구현하기

최근에 이미지 업로드 후 미리보기 기능을 구현하는 방법을 공부하고, 이를 React에서 어떻게 적용할 수 있는지 실습해 보았다. 인터넷을 돌아다니다가 한 개발자 블로그에서 본 코드를 참고하며, 차근차근 코드가 어떻게 작동하는지 이해해보았다.


1. React 훅 사용법 이해하기 🎯


const [imgFile, setImgFile] = useState("");
const imgRef = useRef();
  • useState(""): imgFile 상태를 생성하고, 초기값을 빈 문자열로 설정한다. 사용자가 이미지를 업로드하면 이 상태에 Base64 문자열이 저장된다.

  • useRef(): imgRef를 통해 <input type="file" /> 요소를 참조할 수 있다. 이 참조를 이용해 이미지 파일을 직접 다룬다.

🤔 useRef는 무엇인가요?


`useRef()`는 React에서 **특정 DOM 요소를 직접 참조**할 수 있게 해주는 훅이다. 이를 사용하면 불필요한 렌더링 없이 요소에 접근할 수 있다. 예를 들어, 이미지 파일을 선택하는

<input> 요소를 다룰 때 유용하다.


일반적인 useState 방식으로 파일 가져오기:

const [file, setFile] = useState(null);

const handleFileChange = (e) => {
  setFile(e.target.files[0]);
};

이 방식은 매번 상태를 업데이트하면서 컴포넌트가 다시 렌더링될 수 있어 비효율적이다. 반면, useRef를 사용하면 렌더링을 줄일 수 있다. 🚀



2. saveImgFile 함수 이해하기 🛠️


const saveImgFile = () => {
  const file = imgRef.current.files[0];  // input에서 첫 번째 파일 가져오기
  const reader = new FileReader();  // FileReader 객체 생성
  reader.readAsDataURL(file);  // 파일을 Data URL(베이스64)로 변환
  reader.onloadend = () => {  // 파일 읽기가 끝나면 실행
      setImgFile(reader.result);  // 변환된 데이터 URL을 imgFile 상태에 저장
  };
};
  • imgRef.current.files[0]: 업로드된 파일을 가져온다. files는 배열처럼 동작하기 때문에 첫 번째 파일을 가져오기 위해 files[0]을 사용한다.
  • new FileReader(): 1FileReader1 객체는 파일을 읽고, 이를 Base64 형식의 문자열로 변환해준다.
  • reader.readAsDataURL(file): 파일을 Base64로 변환하여 읽는다.
  • reader.onloadend = () => { - -setImgFile(reader.result); }: 파일을 읽고 변환된 결과를 setImgFile을 통해 상태에 저장한다.

❓ Q: imgRef.current.files[0]은 왜 0인가요?

files는 배열로 다뤄지므로 첫 번째 파일을 가져오기 위해 0을 사용한다. 예를 들어, 여러 파일을 업로드할 수 있는 <input> 요소라면 배열 형태로 여러 파일을 받게 된다.

❓ Q: FileReader()와 readAsDataURL(file)은 어떻게 작동하나요?

FileReader 객체는 파일을 읽고, 그 데이터를 문자열로 변환하는 객체이다. readAsDataURL(file) 메서드는 파일을 Base64 형식의 문자열로 변환하여 데이터를 쉽게 처리할 수 있게 해준다.


3. 이미지 미리보기 렌더링 방법 📷


// 업로드된 이미지 미리보기
<img
  src={imgFile ? imgFile : `/images/icon/user.png`}
  alt="프로필 이미지"
/>

// 이미지 업로드 input
<input
  type="file"
  accept="image/*"
  id="profileImg"
  onChange={saveImgFile}
  ref={imgRef}
/>

<img> 태그에서는 조건부 렌더링을 사용한다.
src={imgFile ? imgFile : '/images/icon/user.png'}imgFile 상태가 존재하면 해당 이미지를 렌더링하고, 없으면 기본 이미지를 보여준다.

<input> 태그에서 onChange 이벤트가 발생하면, 사용자가 파일을 선택할 때마다 saveImgFile 함수가 호출되어 파일을 읽고 상태를 업데이트한다.

❓ Q: src={imgFile ? imgFile : '/images/icon/user.png'}는 왜 이렇게 작성되었나요?

조건부 렌더링을 활용하여, imgFile이 존재하면 업로드된 이미지를, 그렇지 않으면 기본 이미지인 /images/icon/user.png를 보여준다.



4. 전체 과정 정리 📝


1. 상태와 참조 설정

imgFile 상태는 선택한 이미지 데이터를 저장하고, imgRef<input> 요소를 참조하여 파일에 접근한다.


2. 파일 선택 시 처리

saveImgFile 함수가 호출되어 파일을 Base64로 변환하고, 변환된 데이터를 setImgFile을 통해 상태에 저장한다.


3. 미리보기 이미지 표시

<img> 태그는 imgFile이 존재하면 해당 이미지를 렌더링하고, 없으면 기본 이미지를 표시한다.


4. 결과

사용자가 이미지를 업로드하면, 즉시 미리보기가 업데이트된다.




마무리 ✨

사진 파일을 업로드하고 미리보는 기능은 웹 애플리케이션에서 자주 사용되는 기능이다. 이를 구현하기 위해 다양한 도구와 방법이 있지만, React에서 useRefFileReader를 활용하여 간단히 처리할 수 있었다.

앞으로도 계속해서 이런 기능들을 익혀서, 더 능숙하게 사용할 날이 왔으면!



💻 참고 사이트:

profile
안녕하세요

0개의 댓글