form icon indicating copy to clipboard operation
form copied to clipboard

fix(vue-form): losing reactivity

Open j0rgedev opened this issue 8 months ago • 0 comments

Describe the bug

The Vue useForm composable requires a workaround to handle asynchronous default values, which is functional but suboptimal for Vue’s reactivity system. The documentation recommends creating computed properties for each field and wrapping them in a reactive object to maintain reactivity, see https://tanstack.com/form/latest/docs/framework/vue/guides/async-initial-values. For example:

const firstName = computed(() => data.value?.firstName || '');
const lastName = computed(() => data.value?.lastName || '');
const defaultValues = reactive({ firstName, lastName });

const form = useForm({
  defaultValues,
  onSubmit: async ({ value }) => {
    console.log(value);
  },
});

While this works, it is not ideal, especially for forms with many fields, as it requires creating a computed property per field and a reactive wrapper. This may impact performance due to the overhead of multiple reactive proxies. In contrast, the Solid and Svelte adapters use a getter-based API for createForm, which preserves reactivity without requiring individual reactive wrappers for each field. For example: Solid and Svelte Adapter:

const form = createForm(() => ({
  defaultValues: {
    firstName: data?.firstName ?? '',
    lastName: data?.lastName ?? '',
  },
  onSubmit: async ({ value }) => {
    console.log(value);
  },
}));

Your minimal, reproducible example

https://tanstack.com/form/latest/docs/framework/vue/guides/async-initial-values

Steps to reproduce

Use the same code from the docs

Expected behavior

useForm should accept a callback function for its entire configuration, similar to Solid’s createForm. For example:

const form = useForm(() => ({
  defaultValues: {
    firstName: data?.firstName ?? '',
    lastName: data?.lastName ?? '',
    email: data?.email ?? '',
    phone: data?.phone ?? '',
  },
  onSubmit: async ({ value }) => {
    console.log(value);
  },

A pending PR TanStack/form#774 addresses this.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

All platforms

TanStack Form adapter

vue-form

TanStack Form version

1.11.1

TypeScript version

No response

Additional context

Related discussion: https://github.com/TanStack/form/discussions/1278

j0rgedev avatar May 12 '25 04:05 j0rgedev