Hubert
12 min
10 czerwca, 2025

TanStack Form – nowoczesne podejście do formularzy w TypeScript i React

Formularze to nieodłączny element każdej aplikacji webowej — od prostych formularzy kontaktowych po złożone systemy rejestracji. Niestety, wiele popularnych rozwiązań nie nadąża za potrzebami nowoczesnych projektów. TanStack Form to świeże podejście: lekka, typowana i ekstremalnie elastyczna biblioteka, która daje Ci pełną kontrolę nad logiką formularzy — bez zbędnego balastu. Poniższy artykuł wyjaśni Ci, czym jest TanStack Form, jak działa jego architektura, dlaczego wyróżnia się na tle innych bibliotek oraz jak zbudować własny, w pełni typowany i wydajny formularz w React. Zobaczysz praktyczne przykłady, poznasz najlepsze praktyki i dowiesz się, czy to rozwiązanie pasuje do Twojego projektu.

Czytaj więcej
TanStack Form – nowoczesne podejście do formularzy w TypeScript i React

Czym jest TanStack Form?

TanStack Form to nowoczesna, headless (czyli bezwarstwowa UI) biblioteka do zarządzania formularzami, zaprojektowana z myślą o typowaniu, elastyczności i maksymalnej wydajności. Stworzona przez twórców znanych bibliotek takich jak TanStack Table czy TanStack Query, stanowi odpowiedź na ograniczenia narzędzi takich jak Formik czy React Hook Form – szczególnie w większych, silnie typowanych projektach TypeScriptowych.

W przeciwieństwie do wielu bibliotek formularzy, TanStack Form:

– nie narzuca gotowych komponentów UI – daje Ci tylko logikę, a wygląd budujesz sam,

– jest framework-agnostyczna – działa z Reactem, Vue, Angular, Solid, Svelte i innymi,

– nie ma żadnych zewnętrznych zależności – jest lekka i niezależna od kontekstu,

– obsługuje pełne typowanie bez ręcznego podawania generyków – typy pól wnioskowane są automatycznie na podstawie defaultValues,

– wspiera SSR i React Server Components – nadaje się do aplikacji Next.js czy TanStack Start.

Kluczem do jej działania jest reaktywna architektura, dzięki której każda zmiana stanu formularza wpływa tylko na te pola, które rzeczywiście muszą się zaktualizować. Dzięki temu możliwe są bardzo szybkie i wydajne interakcje – nawet w dużych formularzach z dziesiątkami pól i zależności między nimi.

TanStack Form nie jest kolejną biblioteką „do wrzucenia w 10 minut” – to narzędzie dla osób, które chcą mieć pełną kontrolę nad formularzem, jego walidacją, zachowaniem i integracją z logiką aplikacji. Jeśli budujesz aplikacje w TypeScript i zależy Ci na precyzji, elastyczności i solidnych typach – to rozwiązanie zdecydowanie warto poznać.

Potrzebujesz wsparcia w projektach IT?
Potrzebujesz wsparcia w projektach IT?
Potrzebujesz wsparcia w projektach IT?
Napisz do nas!

Jak działa TanStack Form pod maską?

TanStack Form opiera się na reaktywnej, deklaratywnej architekturze, której celem jest pełna kontrola nad logiką formularza – bez narzucania żadnych komponentów UI. Zamiast gotowych inputów czy kontrolek, dostajesz zestaw precyzyjnych narzędzi (useForm, Field, FormApi, FieldApi), które pozwalają budować formularze dokładnie tak, jak wymaga tego projekt – niezależnie od frameworka czy warstwy prezentacji.

useForm – fundament formularza

Hook useForm służy do zainicjowania formularza wraz z wartościami domyślnymi (defaultValues), walidacją i konfiguracją zachowania pól. To właśnie na tym etapie TanStack Form automatycznie wnioskuje typy pól – bez potrzeby ręcznego definiowania generyków. Typy są dokładne i rekurencyjne, co zapewnia maksymalne bezpieczeństwo typowania w TypeScript.

form.Field – logika pól bez szablonu

Obiekt form.Field daje pełny dostęp do logiki konkretnego pola: jego wartości, błędów, statusu (touched, dirty, valid), jak również metod aktualizacji i subskrypcji. Ponieważ biblioteka nie narzuca żadnego UI, możesz dowolnie integrować ją z Tailwindem, Material UI, ShadCN, a nawet czystym HTML-em.

Granularna reaktywność dzięki sygnałom

Jednym z największych atutów TanStack Form jest architektura oparta na sygnałach z @tanstack/store. Oznacza to, że każde pole reaguje tylko na te zmiany, które rzeczywiście go dotyczą – bez re-renderowania całego formularza ani innych niezależnych pól. To ogromna zaleta wydajnościowa, szczególnie w dużych, dynamicznych formularzach.

Zaawansowane API: FormApi i FieldApi

Obiekty FormApi i FieldApi to zaawansowane interfejsy zarządzania formularzem. Umożliwiają globalne sterowanie stanem (setValue, reset, validate, watch, subscribe) oraz lokalne operacje na pojedynczych polach – co daje ogromną kontrolę dla bardziej złożonych przypadków, np. dynamicznych list, formularzy wieloetapowych, czy customowych komponentów.

Walidacja synchroniczna i asynchroniczna

TanStack Form wspiera walidację zarówno natywną (np. required, minLength), jak i opartą na schematach (np. Zod, Valibot, ArkType). Co ważne – możesz stosować walidację asynchroniczną (np. sprawdzanie dostępności e-maila na serwerze), z wbudowanym debounce i kontrolą momentu walidacji (onChange, onBlur, onSubmit). Dodatkowo, za pomocą validators.onSubmitAsync możesz przechwytywać błędy z backendu i mapować je bezpośrednio na pola formularza – co znacznie ułatwia obsługę błędów po stronie serwera.

SSR, React Native i przyszłość

TanStack Form działa nie tylko w aplikacjach SPA – jest w pełni kompatybilny z SSR (Server-Side Rendering), np. w Next.js (w tym App Router), TanStack Start i Remix. Dodatkowo wspiera środowiska mobilne, takie jak React Native, a zespół TanStack pracuje nad dedykowanym DevTools, który ułatwi debugowanie i monitorowanie stanu formularzy w czasie rzeczywistym.

Jak TanStack Form radzi sobie z typowaniem i walidacją?

W świecie TypeScriptu formularze bywają pułapką: ręczne definiowanie typów, niezgodność schematów walidacji z rzeczywistymi danymi, problemy z synchronizacją błędów. TanStack Form rozwiązuje te problemy u samego źródła — poprzez precyzyjne, automatyczne typowanie i elastyczny system walidacji, który działa zarówno synchronicznie, jak i asynchronicznie.

Typowanie bez kompromisów

Największą przewagą TanStack Form jest to, że typy formularza są wnioskowane automatycznie z obiektu defaultValues. Nie musisz ręcznie podawać generyków — biblioteka sama odczytuje strukturę danych i generuje silnie typowany interfejs do każdego pola. Przykład:

const form = useForm({
  defaultValues: {
    email: '',
    age: 0
  }
})

W tym przypadku form.Field("email").state.value ma automatycznie typ string, a form.Field("age").state.valuenumber. Co więcej, te typy są dziedziczone przez wszystkie metody, subskrypcje i walidatory.

Walidacja deklaratywna

Każde pole może mieć przypisaną funkcję walidującą – zarówno synchroniczną (validate) jak i asynchroniczną (validateAsync). Walidacja może odbywać się na różnych etapach: onChange, onBlur, onSubmit, a każda z tych opcji może mieć niezależne debounce. Przykład walidatora synchronicznego:

validate: (value) => {
  if (!value.includes('@')) return 'Niepoprawny e-mail'
}

Walidacja asynchroniczna z debounce

Potrzebujesz sprawdzić dostępność nazwy użytkownika na serwerze? Żaden problem – TanStack Form wspiera funkcje async z pełną kontrolą opóźnień (np. onChangeAsyncDebounceMs: 500) i integracją z loading/error state’em pola.

validateAsync: async (username) => {
  const exists = await checkUsernameExists(username)
  return exists ? 'Ta nazwa jest już zajęta' : undefined
}

Walidacja oparta na schematach

Dla bardziej złożonych formularzy możesz skorzystać z bibliotek walidacyjnych, takich jak Zod, Valibot czy ArkType. Wystarczy, że przekażesz schemat jako validatorAdapter, a biblioteka automatycznie zintegruje go z formularzem — zarówno typowo, jak i runtime’owo. Przykład z Zod:

const schema = z.object({
  email: z.string().email(),
  age: z.number().min(18)
})

useForm({
  defaultValues: { email: '', age: 0 },
  validatorAdapter: zodValidator(schema)
})

Obsługa błędów z serwera

W przypadku walidacji na serwerze (np. REST API lub GraphQL), TanStack Form umożliwia mapowanie błędów backendowych na konkretne pola formularza dzięki onSubmitAsync. Wystarczy, że zwrócisz obiekt errors, a biblioteka automatycznie dopisze je do odpowiednich pól.

Praktyczny przykład – formularz w React z walidacją Zod

Teoria teorią, ale siła TanStack Form ujawnia się naprawdę dopiero w praktyce. Poniżej pokażę, jak zbudować prosty, ale w pełni typowany formularz rejestracyjny w React, z walidacją opartą na Zod i dynamicznym feedbackiem dla użytkownika.

1. Schemat danych i walidacja

Zaczynamy od zdefiniowania schematu danych, czyli struktury formularza oraz zasad walidacji dla każdego pola. Wykorzystujemy do tego bibliotekę Zod, która pozwala deklaratywnie opisać, jak dane powinny wyglądać — a przy okazji automatycznie generuje typy TypeScript. Dzięki temu mamy jedno źródło prawdy zarówno dla logiki walidacyjnej, jak i dla typowania danych w całym formularzu.

import { z } from 'zod'

const schema = z.object({
  name: z.string().min(2, 'Imię musi mieć co najmniej 2 znaki'),
  email: z.string().email('Niepoprawny adres e-mail'),
  age: z.number().min(18, 'Musisz mieć co najmniej 18 lat')
})

type FormValues = z.infer<typeof schema>

2. Inicjalizacja formularza

Używamy hooka useForm, przekazując domyślne wartości oraz adapter walidacyjny Zod:

import { useForm } from '@tanstack/react-form'
import { zodValidator } from '@tanstack/zod-form-adapter'

const form = useForm<FormValues>({
  defaultValues: {
    name: '',
    email: '',
    age: 18,
  },
  validatorAdapter: zodValidator(schema)
})

3. Renderowanie pól

Każde pole tworzymy przy użyciu form.Field. To daje dostęp do wartości, błędów i funkcji aktualizujących:

<form onSubmit={(e) => {
  e.preventDefault()
  form.handleSubmit(async (values) => {
    console.log('Wysłane:', values)
  })
}}>
  <form.Field name="name">
    {(field) => (
      <div>
        <label>Imię</label>
        <input value={field.state.value} onChange={(e) => field.handleChange(e.target.value)} />
        {field.state.meta.touchedErrors && <p>{field.state.meta.touchedErrors}</p>}
      </div>
    )}
  </form.Field>

  <form.Field name="email">
    {(field) => (
      <div>
        <label>Email</label>
        <input value={field.state.value} onChange={(e) => field.handleChange(e.target.value)} />
        {field.state.meta.touchedErrors && <p>{field.state.meta.touchedErrors}</p>}
      </div>
    )}
  </form.Field>

  <form.Field name="age">
    {(field) => (
      <div>
        <label>Wiek</label>
        <input
          type="number"
          value={field.state.value}
          onChange={(e) => field.handleChange(Number(e.target.value))}
        />
        {field.state.meta.touchedErrors && <p>{field.state.meta.touchedErrors}</p>}
      </div>
    )}
  </form.Field>

  <button type="submit">Wyślij</button>
</form>

Co tu się dzieje? Każde pole działa niezależnie – jego stan, walidacja i błędy są obsługiwane lokalnie. Typy są w pełni wnioskowane, nie musisz deklarować typu ręcznie nigdzie w kodzie. Walidacja Zod działa automatycznie – błędy są mapowane do pól i wyświetlane dynamicznie. Możesz dodać debounce, walidację async, pola warunkowe – bez zmiany struktury formularza.

Zalety i wady – czy TanStack Form to dobre narzędzie dla Ciebie?

Choć TanStack Form oferuje potężny zestaw możliwości i nowoczesne podejście do zarządzania formularzami, jak każde narzędzie – nie jest rozwiązaniem uniwersalnym dla wszystkich. Poniżej znajdziesz zestawienie najważniejszych zalet i potencjalnych ograniczeń, które warto wziąć pod uwagę przed wdrożeniem biblioteki w swoim projekcie.

Zalety TanStack Form:

1. Silne, automatyczne typowanie w TypeScript
Typy pól wnioskowane są bezpośrednio z defaultValues, co eliminuje konieczność ręcznego definiowania generyków. Cała logika formularza opiera się na bezpiecznych, statycznych typach.

2. Reaktywność na poziomie pola, nie formularza
Dzięki wykorzystaniu TanStack Store i sygnałów (signals), zmiana w jednym polu nie powoduje re-renderu innych pól. To znacząco poprawia wydajność w dużych formularzach.

3. Pełna kontrola – headless i agnostyczne API
Brak narzuconych komponentów UI oznacza, że możesz używać dowolnego stylu, frameworka czy biblioteki komponentów (Tailwind, Material UI, ShadCN, itp.).

4. Obsługa walidacji sync, async i debounce
TanStack Form obsługuje różne tryby walidacji, w tym walidację opartą na schematach (np. Zod), walidację serwerową oraz debounce – out of the box.

5. SSR-ready i framework-agnostyczny
Działa nie tylko z Reactem, ale też Vue, Solid, Angular, Svelte czy Lit. Wspiera też środowiska SSR jak Next.js, Remix i TanStack Start.

6. Lekka i pozbawiona zależności zewnętrznych
Biblioteka jest bardzo lekka, nie ma żadnych runtime-dependencies, co sprawia, że ładuje się szybko i nie zwiększa bundle size’u aplikacji.

Wady i wyzwania Tanstack Form:

1. Wyższy próg wejścia
Ze względu na headlessowe podejście i brak gotowych komponentów, początkowa integracja może być bardziej czasochłonna niż np. z Formikiem.

2. Mniej materiałów edukacyjnych i przykładów (na razie)
Ponieważ biblioteka jest stosunkowo młoda, w porównaniu do React Hook Form czy Formika ma mniej tutoriali, Stack Overflow-ów i gotowych snippetów.

3. Wymaga znajomości TypeScript
Choć można używać TanStack Form bez TS, pełnię jego możliwości doceniają dopiero użytkownicy dobrze poruszający się w typowaniu złożonych struktur danych.

4. Brak gotowych DevTools (jeszcze)
Obecnie nie ma oficjalnego panelu debugowania (choć jest planowany). W porównaniu do np. React Hook Form DevTools, może to być pewien brak w zaawansowanych projektach.

5. Mniej plug-and-play przy bardzo prostych formularzach
Dla prostych przypadków typu „formularz kontaktowy z trzema polami” inne narzędzia mogą być szybsze do wdrożenia, szczególnie dla juniorów.

Dla kogo TanStack Form będzie najlepszym wyborem?

Dla zespołów pracujących w TypeScript, które potrzebują pełnej kontroli i wydajności.

Dla aplikacji średnich i dużych, które operują na dynamicznych, zależnych od siebie polach formularzy.

Dla projektów wymagających SSR, framework-agnostyczności lub ścisłej integracji z backendem.

Podsumowanie – czy warto sięgnąć po TanStack Form?

TanStack Form to nie kolejna biblioteka formularzy, ale nowoczesne, przemyślane podejście do zarządzania stanem formularza w aplikacjach webowych. Dzięki headlessowej architekturze, silnemu typowaniu, granularnej reaktywności i pełnej elastyczności – daje Ci dokładnie tyle kontroli, ile potrzebujesz, bez narzucania czegokolwiek odgórnie.

Jeśli tworzysz aplikację w TypeScript, potrzebujesz solidnej obsługi walidacji (w tym asynchronicznej), integracji z backendem, a przy tym zależy Ci na wydajności – TanStack Form to narzędzie, które zdecydowanie warto poznać i przetestować.

Nie jest to jednak biblioteka typu „kliknij i działa” – wymaga pewnego zaangażowania i zrozumienia, ale w zamian oferuje skalowalność, bezpieczeństwo i pełną kontrolę, jakiej nie dają inne narzędzia.

Załączniki i materiały dodatkowe o TanStack form:

Oficjalna dokumentacja: https://tanstack.com/form/latest

Repozytorium GitHub: https://github.com/TanStack/form

Sekcja FAQ – najczęściej zadawane pytania o TanStack Form

1. Czym różni się TanStack Form od React Hook Form?
TanStack Form oferuje granularną reaktywność, silniejsze typowanie TypeScript i architekturę headless bez komponentów UI. React Hook Form jest szybszy w prostych przypadkach, ale mniej elastyczny w dużych, dynamicznych formularzach.

2. Jak użyć TanStack Form z walidacją Zod?
Wystarczy zaimportować zodValidator z adaptera @tanstack/zod-form-adapter i podać schemat do validatorAdapter w useForm. Dzięki temu walidacja i typowanie działają jednocześnie.

3. Czy TanStack Form działa z React Query (TanStack Query)?
Tak, biblioteka świetnie integruje się z TanStack Query. Można np. wykonywać walidację async na podstawie danych z API lub wysyłać dane formularza przez mutacje useMutation.

4. Czy TanStack Form ma wbudowane zarządzanie błędami?
Tak – każde pole ma własny meta.errors, meta.touchedErrors i meta.isValid. Dodatkowo możesz obsługiwać błędy po stronie serwera przy pomocy onSubmitAsync i mapować je bezpośrednio na pola.

5. Gdzie znajdę przykłady użycia TanStack Form?
Oficjalna dokumentacja oferuje wiele przykładów dla React, Vue, Angular i innych frameworków: tanstack.com/form/latest/examples. Możesz też szukać sandboxów z frazami jak tanstack form example lub tanstack form composition.

Powiązane artykuły
Zobacz wszystkie
Odkryj więcej tematów