SvelteKit Remote Functions 워크어라운드 헬퍼

발행: (2025년 12월 8일 오전 08:48 GMT+9)
4 min read
원문: Dev.to

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);
    }
};

Issue Tracker

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…
};

Issue Tracker

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
    })
);

Issue Tracker

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

Issue Tracker


지금까지입니다. 발견한 추가적인 우회 방법이 있다면 자유롭게 공유해주세요!

Back to Blog

관련 글

더 보기 »

NextJS와 함께하는 통합 생성 및 편집 폼

소개 이 가이드에서는 새 데이터를 추가하고 기존 데이터를 업데이트하는 두 가지 작업을 모두 처리할 수 있는 통합 폼을 만들 것입니다. 단일 폼을 사용하면 코드 중복을 줄일 수 있습니다.