meta image도 조건부로 db로 올리는 것까지 감안하여야 해서 정말 부끄럽고, 안타까운 코드가 만들어졌다.
const submitEditCard = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const editData: EditPlatFormType = {
...editPlatForm,
};
let comparedData = Object.entries(editData).reduce((acc, [key, value]) => {
if (prevData[key as keyof EditPlatFormType] !== value) {
acc[key as keyof EditPlatFormType] = value;
}
return acc;
}, new Object() as EditPlatFormType);
if (isEmptyObject(comparedData) && prevData.image_url === prevImg) {
resetIsRegist();
resetEditPlatForm();
resetPrevData();
return;
}
if (comparedData.link_url) comparedData.id = editData.id;
comparedData.store_id = editData.store_id;
comparedData.createdAt;
comparedData.id = editData.id;
if (meta) {
console.log('meta');
// 기존 이미지가 있고 이미지 변경 했을 때
if (prevData.image_url) {
if (prevData.image_url.includes(SUPABASE_STORAGE_URL)) {
// opengraph 이미지가 아니면 삭제
await removePlatFormImage(prevData);
}
const { file, createdAt, metaImage, ...updateTarget } = comparedData;
const data = { ...updateTarget, image_url: metaImage };
await updatePlatFormData(data as TablesInsert<'platform'>);
const { platform } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
return;
}
//기존 이미지가 없고 meta이미지만을 등록 할 때
if (!prevData.image_url) {
const { file, createdAt, metaImage, ...updateTarget } = comparedData;
const data = { ...updateTarget, image_url: metaImage };
await updatePlatFormData(data as TablesInsert<'platform'>);
const { platform } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
return;
}
}
if (!meta) {
console.log('!meta');
// 기존이미지가 있고 이미지 변경 했을 때
if (prevData.image_url && comparedData.file) {
comparedData.createdAt = moment().toISOString();
if (prevData.image_url.includes(SUPABASE_STORAGE_URL)) {
// opengraph 이미지가 아니면 삭제
await removePlatFormImage(prevData);
}
// 새로운 이미지 업로드
await uploadPlatFormImage(comparedData);
const { publicUrl: image_url } = downloadPlatFormImageUrl(comparedData);
comparedData = {
...comparedData,
image_url,
};
const { file, createdAt, ...updateTarget } = comparedData;
await updatePlatFormData(updateTarget as TablesInsert<'platform'>);
const { platform } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
return;
}
// 기존데이터에 이미지가 없을 때 이미지 등록을 할 때
if (!prevData.image_url && comparedData.file) {
console.log('여기에 오니?');
comparedData.createdAt = moment().toISOString();
await uploadPlatFormImage(comparedData);
const { publicUrl: image_url } = downloadPlatFormImageUrl(comparedData);
comparedData = {
...comparedData,
image_url,
};
const { file, createdAt, ...updateTarget } = comparedData;
await updatePlatFormData(updateTarget as TablesInsert<'platform'>);
}
// 수정할 때 이미지만 삭제 할 때 실행 되는 조건문
if (!prevImg && !comparedData.link_url && !comparedData.name) {
console.log('여기에 오니?');
// 수정할 이미지가 meta이미지이면
if (!prevData?.image_url?.includes(SUPABASE_STORAGE_URL)) {
const { file, createdAt, ...updateTarget } = comparedData;
console.log(updateTarget);
await updatePlatFormData({ ...updateTarget, image_url: null } as TablesInsert<'platform'>);
const { platform, error } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
return;
}
// 수정할 이미지가 storage 이미지 이면
if (prevData?.image_url!.includes(SUPABASE_STORAGE_URL)) {
await removePlatFormImage(comparedData);
const { file, createdAt, ...updateTarget } = comparedData;
await updatePlatFormData({ ...updateTarget, image_url: null } as TablesInsert<'platform'>);
const { platform, error } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
return;
}
}
}
const { file, createdAt, ...updateTarget } = comparedData;
await updatePlatFormData(updateTarget as TablesInsert<'platform'>);
const { platform } = await fetchPlatForm(store_id!);
setFetchPlatFormData(platform);
resetIsRegist();
resetEditPlatForm();
resetPrevData();
toast('수정이 완료 되었습니다.', {
type: 'info',
position: 'top-center',
showCloseButton: true,
autoClose: 300,
});
};
위 코드를 안 읽었다면 정말 다행이라 생각한다.
간단하게 무슨 함수이냐면, 카드 편집 후 클릭으로 db에 전송하기 전, 추출된 meta image로 수정 되어있는지를 확인 하는 로직을 추가한 코드이다.
위 코드를 보면 어떻게 압축 시킬수 있을까? 생각을 많이 했던것 같다.
역으로도 생각해보고, 공통된 코드가 있는지 확인도 해보았지만, 그 때 당시에는 도무지 어떻게 해야할 도리가 없었다.
그래서 다른 작업을 하다가 갑자기 생각난 것은
라는 생각이 머릿속으로 스쳐지나가
image를 가지고 조건부로 처리하는 함수 하나를 만들면 위의 대단해 엄청난 함수 로직이 줄어 들것 같았다.
따라서 뭔가 반대로 생각하면 될것 같은 " 감 " 을 가지고 생각해본 결과
이미지를 업로드 하기 위해서는 file이 있는지 없는지를 알아야한다. -> file이 없다면 meta image가 있는지 없는지를 알아야 한다.
간단한 문장이지만 이걸 위해 몇 일을 고민했는지 모르겠다.
이것을 함수로 표현 하자면
export const handleImageUpload = async (data: AddPlatFormType | EditPlatFormType) => {
if (data.file) {
data.createdAt = dayjs().toISOString();
await uploadPlatFormImage(data);
const { publicUrl } = downloadPlatFormImageUrl(data);
data.image_url = publicUrl;
return data;
}
data.image_url = data.metaImage ?? null;
return data;
};
// if (meta) {
// console.log('meta');
// // 기존 이미지가 있고 이미지 변경 했을 때
// if (prevData.image_url) {
// if (prevData.image_url.includes(SUPABASE_STORAGE_URL)) {
// // opengraph 이미지가 아니면 삭제
// await removePlatFormImage(prevData);
// }
// const { file, createdAt, metaImage, ...updateTarget } = comparedData;
// const data = { ...updateTarget, image_url: metaImage };
// await updatePlatFormData(data as TablesInsert<'platform'>);
// const { platform } = await fetchPlatForm(store_id!);
// setFetchPlatFormData(platform);
// resetIsRegist();
// resetEditPlatForm();
// resetPrevData();
// toast('수정이 완료 되었습니다.', {
// type: 'info',
// position: 'top-center',
// showCloseButton: true,
// autoClose: 300,
// });
// return;
// }
// //기존 이미지가 없고 meta이미지만을 등록 할 때
// if (!prevData.image_url) {
// const { file, createdAt, metaImage, ...updateTarget } = comparedData;
// const data = { ...updateTarget, image_url: metaImage };
// await updatePlatFormData(data as TablesInsert<'platform'>);
// const { platform } = await fetchPlatForm(store_id!);
// setFetchPlatFormData(platform);
// resetIsRegist();
// resetEditPlatForm();
// resetPrevData();
// toast('수정이 완료 되었습니다.', {
// type: 'info',
// position: 'top-center',
// showCloseButton: true,
// autoClose: 300,
// });
// return;
// }
// }
// if (!meta) {
// console.log('!meta');
// // 기존이미지가 있고 이미지 변경 했을 때
// if (prevData.image_url && comparedData.file) {
// comparedData.createdAt = moment().toISOString();
// if (prevData.image_url.includes(SUPABASE_STORAGE_URL)) {
// // opengraph 이미지가 아니면 삭제
// await removePlatFormImage(prevData);
// }
// // 새로운 이미지 업로드
// await uploadPlatFormImage(comparedData);
// const { publicUrl: image_url } = downloadPlatFormImageUrl(comparedData);
// comparedData = {
// ...comparedData,
// image_url,
// };
// const { file, createdAt, ...updateTarget } = comparedData;
// await updatePlatFormData(updateTarget as TablesInsert<'platform'>);
// const { platform } = await fetchPlatForm(store_id!);
// setFetchPlatFormData(platform);
// resetIsRegist();
// resetEditPlatForm();
// resetPrevData();
// toast('수정이 완료 되었습니다.', {
// type: 'info',
// position: 'top-center',
// showCloseButton: true,
// autoClose: 300,
// });
// return;
// }
// // 기존데이터에 이미지가 없을 때 이미지 등록을 할 때
// if (!prevData.image_url && comparedData.file) {
// console.log('여기에 오니?');
// comparedData.createdAt = moment().toISOString();
// await uploadPlatFormImage(comparedData);
// const { publicUrl: image_url } = downloadPlatFormImageUrl(comparedData);
// comparedData = {
// ...comparedData,
// image_url,
// };
// const { file, createdAt, ...updateTarget } = comparedData;
// await updatePlatFormData(updateTarget as TablesInsert<'platform'>);
// }
// // 수정할 때 이미지만 삭제 할 때 실행 되는 조건문
// if (!prevImg && !comparedData.link_url && !comparedData.name) {
// console.log('여기에 오니?');
// // 수정할 이미지가 meta이미지이면
// if (!prevData?.image_url?.includes(SUPABASE_STORAGE_URL)) {
// const { file, createdAt, ...updateTarget } = comparedData;
// console.log(updateTarget);
// await updatePlatFormData({ ...updateTarget, image_url: null } as TablesInsert<'platform'>);
// const { platform, error } = await fetchPlatForm(store_id!);
// setFetchPlatFormData(platform);
// resetIsRegist();
// resetEditPlatForm();
// resetPrevData();
// toast('수정이 완료 되었습니다.', {
// type: 'info',
// position: 'top-center',
// showCloseButton: true,
// autoClose: 300,
// });
// return;
// }
// // 수정할 이미지가 storage 이미지 이면
// if (prevData?.image_url!.includes(SUPABASE_STORAGE_URL)) {
// await removePlatFormImage(comparedData);
// const { file, createdAt, ...updateTarget } = comparedData;
// await updatePlatFormData({ ...updateTarget, image_url: null } as TablesInsert<'platform'>);
// const { platform, error } = await fetchPlatForm(store_id!);
// setFetchPlatFormData(platform);
// resetIsRegist();
// resetEditPlatForm();
// resetPrevData();
// toast('수정이 완료 되었습니다.', {
// type: 'info',
// position: 'top-center',
// showCloseButton: true,
// autoClose: 300,
// });
// return;
// }
// }
// }
이렇게 비교하면 어마어마한 압축량이 보인다.
이것으로 위에 코드를 바꿔보면
const submitEditCard = useCallback(
async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const comparedData = isPlatFormCardValueChange(prevData, editPlatForm);
if (isEmptyObject(comparedData) && prevData.image_url === prevImg) {
handleResetStateAfterAction(isEdit);
return;
}
comparedData.id = editPlatForm.id;
comparedData.store_id = editPlatForm.store_id;
await prevImageRemove(prevData);
const ensureHttpsUrlData = ensureHttpsUrl(comparedData);
// 여기가 바꾼 곳
const form = await handleImageUpload(ensureHttpsUrlData);
// react-query mutation
editCardPlatForm(form as EditPlatFormType);
setPending(true);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[editPlatForm, prevData, prevImg],
);
이렇게 126줄에서 -> 12줄로 바뀌었다.
멋집니다