SvelteKit Remote Functions 워크어라운드 헬퍼
Source: Dev.to
만약 저와 같은 경우라면, SvelteKit에서 Remote Functions가 나오길 오래… 오래 기다려 왔을 것이고, 이제 정말 멋집니다! 아직 실험 단계이긴 하지만, 절약되는 시간은 priceless(가격을 매길 수 없을 정도)합니다. 아래는 현재 제한 사항, 우회 방법, 그리고 그 상태에 대한 목록입니다.
1. Submit Type
enhance 함수를 컴포넌트 템플릿 밖에서 선언하고 싶을 수도 있습니다. 폼 액션에서는 다음과 같이 타입을 사용합니다:
import type { SubmitFunction } from '@sveltejs/kit';
const onSubmit: SubmitFunction = async ({ formElement }) => {
// …
};
SubmitFunction에 대한 직접적인 import가 없으므로, 다음과 같이 파생시킬 수 있습니다:
type SubmitRemoteFunction = Parameters[0];
const onSubmit: SubmitRemoteFunction = async ({ submit }) => {
try {
await submit();
} catch (error) {
console.error(error);
}
};
2. Form Data
formData가 자동으로 전달되지 않지만, 직접 파생시킬 수 있습니다:
const onSubmit: SubmitRemoteFunction = async ({ submit, form }) => {
const formData = new FormData(form);
// optional conversion
const data = Object.fromEntries(formData);
// You shouldn’t need this since everything is available
// in the form rune itself, but you never know…
};
3. Set Initial Data
문서에서는 fields.set을 사용하라고 제안하지만, 이는 동적이지 않으며 state_referenced_locally 오류를 일으킬 수 있습니다. 또한 이후 변경 시 값을 자동으로 업데이트하지 않습니다. 해결 방법은 하이드레이션 후 폼을 다시 초기화하는 헬퍼를 만드는 것입니다:
export function initForm(init: () => void) {
init();
let hydrated = false;
$effect(() => {
if (!hydrated) {
hydrated = true;
return;
}
init();
});
}
사용 예
initForm(() =>
updateChapterAccessForm.fields.set({
courseId: initialData.course_id,
chapterId: initialData.id,
isFree: !!initialData.is_free
})
);
4. Form Debug
개발 중에 현재 폼 데이터를 출력해 주는 작은 헬퍼 컴포넌트 (SuperForms와 비슷하지만 룬을 사용):
import type { RemoteFormFields, RemoteFormInput, RemoteForm } from '@sveltejs/kit';
const { form }: { form: RemoteForm } = $props();
const fields = $derived(form.fields as RemoteFormFields);
{JSON.stringify(
{
values: fields.value(),
issues: fields.allIssues()
},
null,
2
)}
사용법
<!-- Insert component usage here -->
이것은 개발 도구일 뿐이며 별도의 이슈 트래커는 없습니다.
5. Touched
현재 내장된 touched 혹은 pristine 상태가 없습니다. 아래 훅은 전체 폼이 수정되었는지를 추적합니다:
import type { RemoteForm, RemoteFormInput } from "@sveltejs/kit";
export const useTouched = (
form: RemoteForm
) => {
const initialValue = JSON.stringify(form.fields.value());
return {
get touched() {
return JSON.stringify(form.fields.value()) !== initialValue;
}
};
};
사용 예
const touchForm = useTouched(myForm);
const isSubmitting = $derived(!!myForm.pending);
const isValid = $derived(!myForm.fields.allIssues() && touchForm.touched);
// touchForm.touched
지금까지입니다. 발견한 추가적인 우회 방법이 있다면 자유롭게 공유해주세요!