[JavaScript] FileList는 배열이 아니다.

윤후·2022년 9월 19일
3

JavaScript

목록 보기
16/21

<iuput type='file'>를 사용하면서 하나가 아닌 여러 파일을을 받을 때 데이터를 filter를 사용하거나, map을 사용하려고 했지만, not function이라는 경고와 함께 메소드가 실행되지 않는 것을 볼 수 있었다.

해당 데이터가 배열이 아니라는 말인데, 데이터가 어떻게 들어가고 나가는지 정리하고 기록해두려한다.

FileList

const handleUploadFile = (e) => {
    setUploadFile(uploadFiles);
  };

// html
<input type="file" multiple onChange={(e) => {handleUploadFile(e.target.files)}}/>

위와 같이 <input>에 여러 파일이 들어가고, handleUploadfile이라는 함수에 이벤트 객체가 들어가게 된다. 해당함수는 uploadfile이라는 state로 저장되고, 다시 mapping되어 사용자에게 보여지는 형식이다.

하지만 위와 같이 코드를 짜게 되면 아래와 같은 오류가 생기게 된다.

왜 이렇게 되는 것일까? 하여 해당 이벤트에 생기는 객체를 살펴볼 필요가 있었다. 하여 콘솔을 찍어보니 아래와 같은 fileList가 있는것을 볼 수 있었다.

const handleUploadFile = (e) => {
	console.log(e.target.files)
  };

// html
<input type="file" multiple onChange={(e) => {handleUploadFile(e)}}/>

난 이걸 보고나서 객체형태로 들어가는줄 알고, 해당 데이터를 e.target.files.FileList로 접근했지만, undefined가 나오게 되었다. 그럼 배열도 객체도 아닌 뭐란 말인가..

결론

결론은 이벤트 객체의 FileList는 배열이 아닌 file 객체를 여러개를 담고 있는 유사배열 객체(Array-like)이다. 위처럼 이벤트 핸들러에서 input엘리먼트의 .files로 FileList 배열객체를 참조할 수 있다.

그렇기 때문에 .files[0]접근이나 .length는 사용가능하나, 배열이 아니기 때문에 map, filter, foreach 등을 사용할 수 없는 것이다.

그렇다면 해당 데이터를 배열로 변환후 사용할 수는 없을까?

FileList를 map, filter 등 사용하기

FileList에 해당 메소드를 사용할 수 없는 이유를 알았다면 해결방법은 간단하다. 해당 데이터를 배열의 형태를 바꿔주면 가능하다는 뜻이다.

Array.from으로 유사배열 객체를 Array로 변환해주면 되겠다.

const handleUploadFile = (e) => {
  const uploadFile = Array.from(e.target.files)
	setUploadFile(uploadFiles);
  };

// html
<input type="file" multiple onChange={(e) => {handleUploadFile(e)}}/>

Reference

Why isn't the FileList object an array? - stackoverflow

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글