2023. 9. 15. 13:55ㆍProject Tours/Tour on Plantopia
프로젝트 중에는 서비스 코드가 혼재 되어 있었다. 이미 데이터 관련 부분을 api 폴더에 분리했지만 이미지 부분를 처리하는 부분은 남아 있었는데 사실 이 코드는 그냥 따온 것이라 어떻게 해야할지 고민이 되었다. 일단 코드를 이해하는 것이 첫 번째 과제이다.
const cleanFileName = (fileName: string) => {
const cleanedName = fileName.replace(/[^\w\s.-]/gi, '');
return cleanedName;
};
const readFileAsDataURL = (file: File) => {
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => resolve(e.target?.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
const handleFileSelect = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const file = event.target.files?.[0];
if (!file) return;
try {
const previewUrl = await readFileAsDataURL(file);
setPreviewImg(previewUrl);
const storagePath = `myplant_imgs/${cleanFileName(file.name)}`;
const imageRef = ref(storage, storagePath);
const snapshot = await uploadBytes(imageRef, file);
const url = await getDownloadURL(snapshot.ref);
setImgUrl(url);
} catch (error) {
console.error('파일 업로드 에러:', error);
}
event.target.value = '';
};
https://developer.mozilla.org/ko/docs/Web/API/FileReader/readAsDataURL
FileReader.readAsDataURL() - Web API | MDN
readAsDataURL 메서드는 컨텐츠를 특정 Blob 이나 File에서 읽어 오는 역할을 합니다. 읽어오는 read 행위가 종료되는 경우에, readyState (en-US) 의 상태가 DONE이 되며, loadend (en-US) 이벤트가 트리거 됩니다.
developer.mozilla.org
모르는 내용은 webAPI 내용이었고 방식이 정해진 사진 file 올리기 였다. 이전에 미디어 파일 다룬 경험이 있어서 그런지 이제 webAPI하고 가까워진 느낌이다.
const handleImg = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
const imgUrls = await handleFileSelect(file);
if (!imgUrls) return;
setPreviewImg(imgUrls?.previewUrl);
setImgUrl(imgUrls?.url);
event.target.value = '';
};
컴포넌트에는 이것만 넣었다. 중요한 것은 상태 관리는 컴포넌트 내에서만하고 나머지 데이터 처리는 외부 함수를 통해 처리한다는 것이다.
const cleanFileName = (fileName: string) => {
const cleanedName = fileName.replace(/[^\w\s.-]/gi, '');
return cleanedName;
};
const readFileAsDataURL = (file: File) => {
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => resolve(e.target?.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
export const handleFileSelect = async (file: File) => {
try {
const previewUrl = await readFileAsDataURL(file);
const storagePath = `myplant_imgs/${cleanFileName(file.name)}`;
const imageRef = ref(storage, storagePath);
const snapshot = await uploadBytes(imageRef, file);
const url = await getDownloadURL(snapshot.ref);
return { previewUrl, url };
} catch (error) {
console.error('파일 업로드 에러:', error);
}
};
외부 함수로 다 빼주었다. 고민이 되는 것은 new Promise를 await으로 바꿔야하나 싶었는데 mdn 예시에도 그대로 나와있어서 그냥 놔두었다. 정확히 바꿀 수 있을지는 미지수.
'Project Tours > Tour on Plantopia' 카테고리의 다른 글
[리팩토링] React-Hook-Form 도입 (0) | 2023.09.15 |
---|---|
[리팩토링] 왜 식물 리스트 최신화가 안 이루어지는가? (0) | 2023.09.15 |
렌더링 후 undefined가 먼저 들어가서 수정 데이터 초기값을 못잡는 경우 (0) | 2023.08.27 |
초기에 undefined 처리 어떻게 할 것 인가 (미해결) (0) | 2023.08.23 |
[오늘의 이슈] 절대 경로와 상대 경로, 근데 @는 뭐임? (0) | 2023.08.19 |