input type=file 을 이미지 업로드과 Filelist의 0번째의 파일에 접근하여 dataUrl로 parsing 까지는 마쳐놓은 상태였지만 사용자 편의성을 위해 작성해놓은 로직에 멀티업로드를 추가하는 작업이 필요했다.
이미지를 업로드 후 해당 이미지를 브라우저에서 업로드 한 내용을 보여주려면 File 자체로는 보여줄 수 없다. 여러 방법 중 dataUrl을 사용하는 방법을 사용해보려한다. 개인적으로는 css에서 background-image: url() 안에 들어갔었던 dataUrl이라고 생각했더니 어떤것인지 이해가 쉬웠다.
작업을 진행하기 전 단계를 나누어 보았다.
여러개의 파일을 dataUrl로 변환하고 저장할 배열을 만들어야한다. 허나 fileReader는 하나의 작업을 마쳐야 다음으로 넘어갈 수 있기때문에 promise로 만들어야했다.
dataUrl로 변환된 배열이 만들어지면 해당 배열을 돌면서 새로운 객체를 만들어 리턴해주었다.
마지막 useState의 set함수를 이용하여 state에 반영해주었다.
똑같은 이미지를 연속으로 넣었을때에 React는 같은 값으로 인지하기에 렌더링 및 state변화가 일어나지 않았던것 같다. 맞는 방법인지는 모르겠으나, e.target.value = '' 를 활용해서 값을 계속 비워주었다.
const readFile(file: File) => {
return new Promise((resolve) => {
const rader = new FileReader();
reader.addEventListener('load' () => resolve(reader.result), false);
})
}
const makeDataUrl = (files: FileList) => {
return Promise.all(Array.from(files).map((v) => readFile(v)))
}
const uploadImages = async (e) => {
try {
const dataUrl = await makeDataUrl(e.target.files);
const newData = dataUrl.map((v) => {
increasingRefId.current += 1;
return {
sampleData1: increasingRefId.current,
samplePreviewDataUrl: v,
};
});
setSampleState({
...sampleState,
sampleImgArray: [...sampleState.sampleImgArray, ...newData],
});
} catch (error) {
console.log(error);
}
e.target.value = '';
};