일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- CSS
- 코드공유
- JavaScript
- 프론트엔드
- 웹디자인기능사실기
- 슬라이드전환
- 웹퍼블리셔
- 웹디실기
- react
- JS
- Supabase
- 비전공자
- 생활코딩
- 렛츠기릿자바스크립트
- 깃
- 자바스크립트
- git
- 연산자
- 실기
- 웹디자인기능사
- 리액트
- 세로메뉴바
- 정보처리기사
- github
- PROJECT
- jQuery
- 타입스크립트
- 코딩독학
- HTML
- web
- Today
- Total
코딩하는라민
[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(단일 이미지) 본문
[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(단일 이미지)
코딩하는라민 2023. 3. 18. 00:54[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(단일 이미지)
이미지 업로드하고 프리뷰를 하는 여러 블로그들을 서칭하고, 적용해보았다.
이미지 1개 업로드하는 것은 성공했는데 여러 이미지를 업로드하는 것은 성공하지 못했다.
그러던 중 하나의 블로그를 발견했고 겨우 성공할 수 있었다.
물론 버튼을 개별적으로 지우는 것은 이 블로그를 보고 성공하지 못했다..
결국 그분의 도움을.. ha ha
📌 FileReader 생성자
먼저 FileReader 에 대해 알아야한다.
FileReader 생성자는 웹 플랫폼에서 파일을 읽을 수 있는 객체이다.
File, Blob 등의 파일 객체를 읽을 수 있도록 지원한다.
- Blob 에 대해서는 추후 더 알아봐야겠다.
이 생성자는 파일 객체를 읽는데 필요한 메소드와 이벤트를 제공한다.
예를 들어 readAsDataURL() 메소드를 사용하면 파일을 base64 형식으로 읽을 수 있다.
FileReader는 파일을 읽는 동안 발생하는 이벤트를 사용하여 읽은 데이터의 진행 상황을 추적할 수 있다.
✅ base64란?
base64는 8비트 이진 데이터를 64개의 문자로 이루어진 문자열로 변환하는 인코딩 방식이라고 한다..
데이터는 그대로 저장하기에는 용량이 크기 때문에 이진 데이터를 문자열 형태로 변환하여 저장하거나 전송하는 것이 효율적이기 때문이다..
이렇게 변환된 문자열은 ASCII 문자 코드로 표현할 수 있기 때문에 문자열 형태로 저장하거나 전송하기에 적합하다.
또한 이렇게 bse64로 인코딩된 데이터는 다른 프로그램에서도 인식할 수 있으며, 암호화된 데이터를 표현할 때도 사용한다.
📌 파일 업로드하는 코드(단일 이미지) → FileReader API
const [postImg, setPostImg] = useState([]);
const [previewImg, setPreviewImg] = useState([]);
function uploadFile(e) {
let fileArr = e.target.files;
setPostImg(Array.from(fileArr));
let fileRead = new FileReader();
fileRead.onload = function(){
setPreviewImg(fileRead.result);
};
fileRead.readAsDataURL(file[0]);
};
위처럼 postImg 와 preview 이미지 state 를 따로 관리하는 이유가 있다.
서버에 저장하는 데이터는 파일 자체를 저장하는 것고,
프리뷰에 사용하는 데이터는 미리보기 이미지를 생성하기 위한 것이기 때문이다.
원본 이미지 파일 자체는 용량이 크기 때문에 이렇게 따로 분리해서 사용하는 것이다.
즉, 데이터를 보다 효율적으로 관리하기 위한 방법인 것이다!
📌 코드 자세히 뜯어보기
✅ 파일, 파일 url 의 state
const [postImg, setPostImg] = useState([]);
const [previewImg, setPreviewImg] = useState([]);
첫번째 state 는 이미지 파일 자체의 상태이다.
두번째 state 는 이미지 파일의 url 을 담는 상태이다.
✅ input onChange 이벤트 걸기
우선 input 은 모양이 못생겨서 display: none; 으로 감춰둔다.
label 을 스타일링해서 background 도 넣어주었다.
이제 label 부분을 클릭하면 input의 onChange 이벤트가 발생될 것이다.
<WriteInput accept=".png, .jpeg, .jpg" type="file"
onChange={handleFileUpload}
/>
label{
display: inline-block;
width: 90px;
height: 90px;
background: url('src/assets/icon-add-photo.svg') no-repeat;
background-position: center;
border: 1px solid ${gray4};
border-radius: 10px;
cursor: pointer;
}
input{
display: none;
}
✅ 입력한 input 의 files 가져오기
function handleFileUpload(e) {
let fileArr = e.target.files;
input 에 업로드한 파일들을 fileArr 변수에 담는다.
✅ files 을 state 에 업데이트
setPostImg(Array.from(fileArr));
업로드한 files 를 배열로 만들고, state 에 업데이트한다.
console.log(fileArr);
✅ files 의 url 을 담을 변수 선언 & 빈배열 할당
let fileURLs = [];
이제 이곳에 url 을 담아줄 것이다.
✅ 파일 데이터를 읽어올 수 있는 생성자 생성
let fileRead = new FileReader();
FileReader 객체를 생성한다.
이 객체를 이용하여 이미지 파일의 내용을 읽어올 수 있다.
console.log(fileRead);
✅ 생성자에 onload 이벤트 걸기
FileRead.onload = () => {
fileRead 객체의 onload 이벤트 핸들러에 함수를 할당한다.
onload 이벤트는 파일의 내용을 읽어온 후에 호출된다.
이때 읽어온 파일의 내용을 이용하여 미리보기에 사용할 이미지 URL을 만든다.
✅ fileURL 을 state에 업데이트
setPreviewImg(FileRead.result);
setPreviewImg (setState) 함수를 이용해서 URL 을 업데이트한다.
FileRead.result 를 통해 이미지 파일의 내용을 URL의 형태로 읽어온다.
result 는 FileReader 객체에서 읽어들인 데이터를 저장하는 속성이다.
base64로 인코딩된 '문자열 형태'의 데이터를 가지고 있다.
이 데이터를 이용해 이미지 파일을 브라우저에 출력하거나, 서버로 전송하는 등의 작업을 할 수 있는 것이다!
console.log(previewImg);
✅ readAsDataURL 을 이용해 파일 내용 읽어오기
FileRead.readAsDataURL(file[0]);
readAsDataURL() 메서드는 FileReader 인터페이스에서 제공하는 메서드 중 하나이다.
File 객체나 Blob 객체의 내용을 비동기적으로 읽어들여 Data URL 형태로 반환한다.
즉 파일 내용을 Base64 형식의 문자열로 변환해주는 것이다.
해당 Data URL을 이미지 프리뷰에 사용하기 위해 사용한 것이다.
이것을 해주지 않았을 경우 img 태그 내에서 사용할 수 있는 URL 로 변환되지 않기 때문에 파일은 업로드되지 않는다.
✅ 업로드한 파일을 img 태그에 반영해주기
<img alt={previewImg} src={previewImg} />
✅ 완성
FileReader 인터페이스를 사용하면 파일의 내용을 다양한 형태로 읽어들일 수 있기 때문에, 이를 활용하여 다양한 기능을 구현할 수 있다.
✅ 정리
- 데이터를 효율적으로 관리하기 위해 서버에 업로드하는 파일 데이터와, 프리뷰에 사용하는 파일 데이터를 분리해서 state 로 관리해준다.
- 파일을 업로드하기 위해서는 FileReader 라는 생성자를 이용해야 한다.
- 이 생성자는 웹에서 파일을 데이터를 읽어와 문자열 형태로 만들어 적은 용량으로도 이를 관리할 수 있게 해준다.
- onload 이벤트를 통해 파일을 읽어들인 후 result 속성을 통해 이미지를 브라우저에 보여지게 할 수 있다.
- 또한 이 파일의 링크를 readAsDataURL이라는 메서드를 통해 파일의 내용을 읽어들여 img 태그의 src 속성 값으로 사용할 수 있다.
✅ 다중 이미지 업로드 & 프리뷰하기
참고 : rachaen's velog-[리액트] 이미지 여러장 올려서 확인하기, ChatGPT(사랑해요)
등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.
🔅 멋쟁이사자처럼 프론트엔드 4기 파이널 프로젝트
📝 당근마켓 클론코딩
🧑🏻💻 작업 인원 : 5인
🕑 프로젝트 기간 : 23.03.10 ~ 03.28
🔧 기술 스택
• Toolchains : Vite
• Style : Styled Component
• 상태 관리 : Recoil
• Severless : Firebase
'프로젝트 관련 > Project' 카테고리의 다른 글
[React/Project] Recoil Persist 를 사용해 로컬스토리지에 데이터 저장/불러오기 (0) | 2023.03.25 |
---|---|
[React/Project] input 으로 업로드한 여러 개의 이미지 하나씩 삭제하기 (0) | 2023.03.18 |
[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(다중 이미지) (0) | 2023.03.18 |
[React/Project] input disabled 를 이용한 다중 입력값에 따른 버튼 활성/비활성화 (1) | 2023.03.17 |
[React/Project] 파이널 프로젝트 시작 ( 당근마켓 클론코딩 ) (0) | 2023.03.14 |