Skip to content

Commit

Permalink
Feature : 이미지 업로드 에러 해결 (#592)
Browse files Browse the repository at this point in the history
* fix: cancleQueries로 쿼리 취소 후, onSettled에서 항상 데이터 요청

* refactor: 함수명 분명하게 수정

* fix : 이미지 업로드 에러 해결

* refactor : previewImage상태를 useFileUpload훅에서 관리
  • Loading branch information
guesung committed Jan 26, 2024
1 parent 790de67 commit a4e9ff2
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ export default function UploadSection({ control }: ImageThumbnailProps) {
name: 'imageUrl',
control,
});
const { field: previewImageField } = useController({
name: 'previewImage',
control,
});

const { handleFileUploadClick } = useFileUpload(async (files) => {
const { handleFileUploadClick, previewImage } = useFileUpload(async (files) => {
field.onChange(files[0]);
}, previewImageField);
});

return (
<Flex
Expand All @@ -33,13 +29,13 @@ export default function UploadSection({ control }: ImageThumbnailProps) {
className="relative mx-20 aspect-[8/5] overflow-hidden rounded-8 bg-sub"
onClick={handleFileUploadClick}
>
<RenderImage previewImage={previewImageField.value} />
<RenderImage previewImage={previewImage} />
</Flex>
);
}

interface RenderImageProps {
previewImage: string;
previewImage: string | undefined;
}

const RenderImage = memo(function ({ previewImage }: RenderImageProps) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useController } from 'react-hook-form';

import CountryBotoomSheet from './CountryBotoomSheet';
import { Step1Props } from './Step1.client';
import { formatBirthDTO } from '../../util';
Expand All @@ -17,6 +15,7 @@ import { TextField, TextFieldController } from '@/components/TextField';
import { personalityList } from '@/constants/personalityList';
import { useFileUpload } from '@/hooks/useFileUpload';
import { useModal } from '@/hooks/useModal';
import { useController } from 'react-hook-form';

interface Step1InputFormProps extends Step1Props {}

Expand All @@ -29,12 +28,15 @@ export default function Step1InputForm({ onPrev }: Step1InputFormProps) {
const personalities = watch('personalities');

const {
field: { value, onChange },
field: { value, onChange: onChangeImageUrl },
} = useController({
name: 'imageUrl',
control,
});
const { handleFileUploadClick, isPending } = useFileUpload((files) => onChange(files[0]));

const { handleFileUploadClick, previewImage, isPending } = useFileUpload((files) =>
onChangeImageUrl(files[0])
);

const isAllTyped = formState.isValid && !!watch('gender') && personalities.length;

Expand Down Expand Up @@ -69,8 +71,8 @@ export default function Step1InputForm({ onPrev }: Step1InputFormProps) {
imageUrl={value}
size="large"
iconVariant="draft_orders"
isPending={isPending}
onClick={handleFileUploadClick}
isPending={isPending}
/>
</Flex>
<Spacing size={16} />
Expand Down
23 changes: 0 additions & 23 deletions src/components/Image/ImageWithPlaceholder.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Image/index.ts
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
export { default as ImageWithPlaceholder } from './ImageWithPlaceholder';
8 changes: 8 additions & 0 deletions src/hooks/getBase64FromImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function getBase64FromImage(file: File): Promise<string | undefined> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result?.toString());
reader.onerror = (error) => reject(error);
});
}
26 changes: 13 additions & 13 deletions src/hooks/useFileUpload.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { getBase64FromImage } from './getBase64FromImage';
import { usePostFiles } from '@/apis/common';
import { useCallback, useState } from 'react';
import { ControllerRenderProps, Field } from 'react-hook-form';
import { useState } from 'react';

interface UseImageUploadProps {
/**
* 파일 업로드가 완료되었을 때 실행할 함수를 지정합니다.
*/
handleFileChange: (fileUrlList: string[]) => void;
previewImageField: ControllerRenderProps<any, any>;
options?: {
/**
* 업로드할 파일의 타입을 지정합니다. (default: image/*)
Expand All @@ -22,24 +21,24 @@ interface UseImageUploadProps {

export function useFileUpload(
handleFileChange: UseImageUploadProps['handleFileChange'],
previewImageField?: UseImageUploadProps['previewImageField'],
options?: UseImageUploadProps['options']
) {
const { mutate, isPending } = usePostFiles();
const [previewImage, setPreviewImage] = useState<string | undefined>();

const handleFileUploadClick = useCallback(() => {
const handleFileUploadClick = async () => {
const input = document.createElement('input');
input.style.display = 'none';
input.type = 'file';
input.accept = options?.accept || 'image/*';
input.multiple = options?.multiple || false;
input.onchange = (event) => {
document.body.appendChild(input);
input.addEventListener('change', async (event) => {
const { files } = event.target as HTMLInputElement;
if (!files) return;
const reader = new FileReader();
reader.onload = () => {
previewImageField && previewImageField.onChange(reader.result);
};
reader.readAsDataURL(files[0]);

const base64 = await getBase64FromImage(files[0]);
setPreviewImage(base64);

mutate(
{ fileList: Array.from(files) },
Expand All @@ -49,12 +48,13 @@ export function useFileUpload(
},
}
);
};
});
input.click();
}, [handleFileChange, mutate, options?.accept, options?.multiple, previewImageField]);
};

return {
handleFileUploadClick,
isPending,
previewImage,
};
}
20 changes: 0 additions & 20 deletions src/utils/getBase64.ts

This file was deleted.

0 comments on commit a4e9ff2

Please sign in to comment.