Skip to content

Commit

Permalink
refactor: FilePicker에서 setValue 대신에 useController 사용
Browse files Browse the repository at this point in the history
  • Loading branch information
yeolyi committed Mar 8, 2025
1 parent 9cea078 commit 97858f6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 35 deletions.
13 changes: 5 additions & 8 deletions actions/council.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,13 @@ export const deleteCouncilReportAction = async (id: number) => {
const councilRulesPath = getPath(councilRules);

export const putCouncilRulesAction = withErrorHandler(
async (bylawFormData: FormData, constitutionFormData: FormData) => {
console.log(bylawFormData);
console.log(constitutionFormData);

decodeFormDataFileName(bylawFormData, 'newAttachments');
decodeFormDataFileName(constitutionFormData, 'newAttachments');
async (bylawFormData?: FormData, constitutionFormData?: FormData) => {
if (bylawFormData) decodeFormDataFileName(bylawFormData, 'newAttachments');
if (constitutionFormData) decodeFormDataFileName(constitutionFormData, 'newAttachments');

await Promise.all([
putCouncilRules('bylaw', bylawFormData),
putCouncilRules('constitution', constitutionFormData),
bylawFormData && putCouncilRules('bylaw', bylawFormData),
constitutionFormData && putCouncilRules('constitution', constitutionFormData),
]);

revalidateTag(FETCH_TAG_COUNCIL_RULES);
Expand Down
46 changes: 30 additions & 16 deletions app/[locale]/community/council/rules/edit/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,41 @@ export default function CouncilByLawsEditClientPage({ councilRules }: Props) {
});
const router = useRouter();

const { handleSubmit } = methods;
const {
handleSubmit,
formState: { dirtyFields },
} = methods;

const onCancel = () => {
router.back();
};

const onSubmit = handleSubmit(async (formData: FormData) => {
const bylawsDeleteIds = getAttachmentDeleteIds(formData.bylawAttachments, bylawAttachments);
const bylawsFormData = contentToFormData('EDIT', {
requestObject: { deleteIds: bylawsDeleteIds },
attachments: formData.bylawAttachments,
});
const bylawsFormData = dirtyFields.bylawAttachments
? (() => {
const bylawsDeleteIds = getAttachmentDeleteIds(
formData.bylawAttachments,
bylawAttachments,
);
return contentToFormData('EDIT', {
requestObject: { deleteIds: bylawsDeleteIds },
attachments: formData.bylawAttachments,
});
})()
: undefined;

const constitutionDeleteIds = getAttachmentDeleteIds(
formData.constitutionAttachments,
constitutionAttachments,
);
const constitutionFormData = contentToFormData('EDIT', {
requestObject: { deleteIds: constitutionDeleteIds },
attachments: formData.constitutionAttachments,
});
const constitutionFormData = dirtyFields.constitutionAttachments
? (() => {
const constitutionDeleteIds = getAttachmentDeleteIds(
formData.constitutionAttachments,
constitutionAttachments,
);
return contentToFormData('EDIT', {
requestObject: { deleteIds: constitutionDeleteIds },
attachments: formData.constitutionAttachments,
});
})()
: undefined;

await putCouncilRulesAction(bylawsFormData, constitutionFormData);
});
Expand All @@ -63,11 +77,11 @@ export default function CouncilByLawsEditClientPage({ councilRules }: Props) {
<FormProvider {...methods}>
<Form>
<Form.Section title="학생회칙" mb="mb-10" titleMb="mb-2">
<Form.File name="constitutionAttachments" multiple />
<Form.File name="constitutionAttachments" multiple rules={{ required: true }} />
</Form.Section>

<Form.Section title="세칙" titleMb="mb-2">
<Form.File name="bylawAttachments" multiple />
<Form.File name="bylawAttachments" multiple rules={{ required: true }} />
</Form.Section>

<Form.Action onCancel={onCancel} onSubmit={onSubmit} />
Expand Down
24 changes: 13 additions & 11 deletions components/form/File.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { ChangeEventHandler, MouseEventHandler } from 'react';
import { RegisterOptions, useFormContext, useWatch } from 'react-hook-form';
import { FieldValues, RegisterOptions, useController, useFormContext } from 'react-hook-form';

import ClearIcon from '@/public/image/clear_icon.svg';

import { EditorFile, LocalFile } from '../../types/form';

interface FilePickerProps {
name: string;
options?: RegisterOptions;
rules?: Omit<
RegisterOptions<FieldValues, string>,
'setValueAs' | 'disabled' | 'valueAsNumber' | 'valueAsDate'
>;
multiple?: boolean;
}

export default function FilePicker({ name, options, multiple = true }: FilePickerProps) {
const { register, setValue } = useFormContext();
const files = useWatch({ name }) as EditorFile[];

register(name, options);

export default function FilePicker({ name, rules, multiple = true }: FilePickerProps) {
const { control } = useFormContext();
const {
field: { value: files, onChange },
} = useController({ name, rules, control });
// 성능 확인 필요
const handleChange: ChangeEventHandler<HTMLInputElement> = (e) => {
if (e.target.files === null) return;
Expand All @@ -26,7 +28,7 @@ export default function FilePicker({ name, options, multiple = true }: FilePicke
file,
}));

setValue(name, [...files, ...newFiles]);
onChange([...files, ...newFiles]);

// 같은 파일에 대해서 선택이 가능하도록 처리
// https://stackoverflow.com/a/12102992
Expand All @@ -36,7 +38,7 @@ export default function FilePicker({ name, options, multiple = true }: FilePicke
const deleteFileAtIndex = (index: number) => {
const nextFiles = [...files];
nextFiles.splice(index, 1);
setValue(name, nextFiles);
onChange(nextFiles);
};

return (
Expand All @@ -47,7 +49,7 @@ export default function FilePicker({ name, options, multiple = true }: FilePicke
self-start rounded-sm border-[1px] border-neutral-200 bg-neutral-50
`}
>
{files.map((item, idx) => (
{(files as EditorFile[]).map((item, idx) => (
<FilePickerRow
// 순서를 안바꾸기로 했으니 키값으로 인덱스 써도 ㄱㅊ
key={idx}
Expand Down

0 comments on commit 97858f6

Please sign in to comment.