FileReader 로 여러 이미지 파일 동시에 첨부하기 ( + Next/React, TypeScript )

퍼렁꽁치·2022년 4월 1일
2

이전 프로젝트에서 FileReader 로 이미지 파일 여러개를 첨부하는 코드를 그대로 현재 프로젝트에 적용했는데 문제가 발생했다
동시에 여러개, 2~3개의 사진을 첨부하면 FileReader 로 읽어서 readAsDataURL 메서드가 돌아서 사진을 데이터URL 로 돌려줘야 하는데 가장 마지막 사진을 제외하곤 null 이 떴다

아마도 반복문을 돌리면서 각각의 사진을 dataURL 로 읽기전에 다음 반복이 돌면서 덮어버려서 하는게 아닐까 추측이 됐다.
때문에 구글에서 검색하던 중 MDN 에서 제공하는 다른 방법을 적용해서 성공했다.

onst InputFileForm: FC = () => {
  const [images, setImages] = useState<string[]>([])
  
  const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files!
    if (!files[0]) return
    if ((images.length + files.length) > 10) {
      return alert('최대 10개 사진만 첨부할 수 있습니다.')
    }
    const readAndPreview = (file: any) => {
      if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
        const reader = new FileReader()
        reader.onload = () => setImages(prev => [...prev, reader.result as string])
        reader.readAsDataURL(file)
      }
    }
    if (files) {
      [].forEach.call(files, readAndPreview)
    }
  }

  return (
	 // ...

일단 e.target.files 이 하나도 없다면 아무 사진도 첨부되지 않은 것이기 때문에 그대로 종료시키도록 했고,
첨부하려는 사진이 10개 이상이면 사진 첨부를 취소시키고 알림창을 띄었다.

그리고 readAndPreview 함수를 정의했는데, file 을 인자로 받아서 파일명이 jpg, jpeg, png, gif 일 경우 new FileReader() 를 실행시킨 뒤
readAsDataURL 을 돌리고 모두 로드가 되면 images state 배열에 추가하도록 했다.

그리고 밑에가 핵심인데 다시 한번 files 목록이 있다면 [].forEach.call(files, readAndPreview) 코드를 통해서 readAndPreview 함수를 반복실행해서
각각의 사진들이 DataURL 로 읽히도록 해서 images 배열에 넣어 해결했다.

profile
무엇이든 될 수 있는 멋쟁이 토마토🍅 프론트 꿈나무💙

1개의 댓글

comment-user-thumbnail
2022년 5월 24일

덕분에 잘 해결했습니다
감사합니다 ㅎㅎㅎ

답글 달기