코딩하는라민

[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(다중 이미지) 본문

프로젝트 관련/Project

[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(다중 이미지)

코딩하는라민 2023. 3. 18. 16:41
728x90
반응형

[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(다중 이미지)

 

 

📌 단일 이미지 업로드 및 프리뷰 구현

 

[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(단일 이미지)

[React/Project] input 파일 이미지 업로드 & 미리보기(Preview) 기능 구현(단일 이미지) 이미지 업로드하고 프리뷰를 하는 여러 블로그들을 서칭하고, 적용해보았다. 이미지 1개 업로드하는 것은 성공했

ramincoding.tistory.com

 

📌 파일 업로드하는 코드(다중 이미지)

이미지 출처 - 조코딩

다중 이미지를 업로드하기 위해서는 반복문을 사용해야한다.

파일을 업로드하면 files 에 여러개의 파일 데이터가 들어올 것이고, 이를 배열로 만들어서 하나씩 뿌려줘야하기 때문이다.

const [postImg, setPostImg] = useState([]);
const [previewImg, setPreviewImg] = useState([]);

function uploadFile(e) {
    let fileArr = e.target.files;
    setPostImg(Array.from(fileArr));

    let fileUrl = [];
    for(let i = 0; i < fileArr.length; i++){
        let fileRead = new FileReader();
        fileRead.onload = function(){
            fileUrl[i] = fileRead.result;
            setPreviewImg([...fileUrl]);
            fileRead.readAsDataURL(fileArr[i]);
        }
    };
}

 

📌 코드 자세히 뜯어보기

✅ state

state 는 단일 이미지 업로드 방식과 같다.

const [postImg, setPostImg] = useState([]);
const [previewImg, setPreviewImg] = useState([]);

 

✅ 업로드한 files 가져와서 배열로 만들어주기

function uploadFile(e) {
    let fileArr = e.target.files;
    setPostImg(Array.from(fileArr));

배열로 만들어준 files 를 state에 업데이트해준다.

 

✅ 파일의 url 을 넣어줄 빈 배열 생성

let fileUrl = [];

 

 반복문 추가

반복문은 파일의 개수만큼 반복한다.

for(let i = 0; i < fileArr.length; i++){

 

FileReader 생성자와 onload 이벤트 걸기

let fileRead = new FileReader();
fileRead.onload = function(){

FileReader 생성자를 통해 파일 데이터를 읽어온다.

그리고 읽어들인 파일에 onload 이벤트를 걸어 콜백함수에 데이터를 문자열로 변환해주도록 한다.

 

파일의 갯수만큼 해당 인덱스에 해당하는 url 를 차례대로 할당해주기

fileUrl[i] = fileRead.result;

fileRead.result 의 길이는 업로드한 파일의 길이와 같다.

반복문을 돌아 0부터 파일의 개수만큼 반복하게 되는데,

i가 0일 때 fileUrl 의 0번째 요소로 fileRead.result 의 첫번째 요소가 할당되는 것이고 이것을 업로드한 파일의 길이만큼 횟수를 반복하게 된다.

결국 파일의 길이와 url 의 길이는 같게 된다.

 

 파일 url 업데이트

setPreviewImg([...fileUrl]);

fileUrl 배열의 모든 요소를 펼쳐서 인자로 전달한다.

setPreviewImg() 함수에 fileUrl 배열 전체를 인자로 전달하여 상태 값을 업데이트하는 것이다.

 

 

인덱스에 따라 readAsDataURL 을 이용해 파일 내용 읽어오기

fileRead.readAsDataURL(fileArr[i]);

 

✅ 리스트 렌더링

{
    previewImg.map((imgSrc, i) => 
        <ProductImage key={i}>
            <button type="button">
              <img alt="업로드 이미지 제거" src="src/assets/icon-close-button.svg" />
            </button>
            <img alt={imgSrc} src={imgSrc} />
        </ProductImage>
    )
}

map 함수로 배열을 순회하면서 리스트 렌더링하기.

리스트 렌더링에는 고유한 key 가 필요하다.

 

✅ 조건부 렌더링 & 완성

{
    postImg.length>=3 ? '' : <ProductImage/>
}

만약 파일의 길이에 제한을 둔다면 제한을 둔 개수에 따라서 마지막 div 가 안보이도록 해줄 수 있다.

파일의 갯수 제한을 3으로 둔다면,

이미지 출처 - https://jjester.tistory.com/126

이렇게 렌더링이 되도록 해줄 수 있는 것이다!

 

 

 

 


참고 :  rachaen's velog - [리액트] 이미지 여러장 올려서 확인하기
  등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

 

🔅 멋쟁이사자처럼 프론트엔드 4기 파이널 프로젝트

📝 당근마켓 클론코딩

🧑🏻‍💻 작업 인원 : 5인

🕑 프로젝트 기간 : 23.03.10 ~ 03.28

🔧 기술 스택

    • Toolchains : Vite

    • Style : Styled Component

    • 상태 관리 : Recoil

    • Severless : Firebase

 

728x90
반응형