Capítulo 10 de 29

Chapter 10: Async Initial Values

Core Idea

There's no built-in "async defaultValues" option — the documented pattern is to fetch with TanStack Query (or any async source) first, gate rendering on isLoading, and only construct the useForm call once real data is available.

Key Concepts

  • defaultValues is read once at form-instance creation — it isn't reactive to a later-arriving async value on its own, so the fetch must resolve before useForm runs with real data.
  • The common pairing is useQuery (ch025 of tanstack-query-docs, if present) supplying data, with defaultValues: { field: data?.field ?? '' } as a fallback while loading.
  • A loading guard (if (isLoading) return <p>Loading...</p>) prevents rendering the form with empty/wrong defaults before the fetch resolves.

Worked Example

Fetch first, form second: call useQuery to load the record, branch on isLoading to show a placeholder, and only reach the useForm call (with defaultValues sourced from data) once loading is false. Because useQuery caches by queryKey, repeat mounts of the same form don't re-fetch unnecessarily — the async-initial-values problem and TanStack Query's caching solve each other simultaneously rather than needing separate plumbing.

const { data, isLoading } = useQuery({
  queryKey: ['data'],
  queryFn: async () => fetchProfile(),
})

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

if (isLoading) return <p>Loading...</p>
// render form

Key Takeaways

  1. Don't try to update defaultValues reactively after the form is created — gate the useForm call itself behind the loading state instead.
  2. This is the natural integration point with TanStack Query; if that skill is present in this library, its caching/staleness rules (its ch009 "Important Defaults") directly affect how often this "loading" branch is hit.
  3. If the async source can fail, decide explicitly what defaults to fall back to (?? '' in the example) rather than leaving fields undefined, which can trigger the "uncontrolled to controlled" warning (ch023 Debugging).

Connects To

  • Ch023 Debugging: the controlled-input warning this pattern avoids.
  • tanstack-query-docs (sibling skill, if present): the caching layer this pattern typically relies on.