Skip to Content
@alza/hateoasReact Hook FormGetting started

@alza/hateoas-react-hook-form

React Hook Form integrace pro @alza/hateoas formuláře.

Installation

yarn add @alza/hateoas-react-hook-form --exact

Peer dependencies required in your application:

  • react
  • react-hook-form
  • @alza/hateoas

Základní použití

import { useHateoasForm } from "@alza/hateoas-react-hook-form"; import type { HateoasFormV2, HateoasFieldMap } from "@alza/hateoas"; const fieldMap = { token: ["token", "string"], password: ["password", "string"], } as const satisfies HateoasFieldMap; export function Example({ form }: { form: HateoasFormV2 }) { const hf = useHateoasForm(form, fieldMap, t, callClientApi); return ( <form onSubmit={hf.handleSubmit(async (values) => { await hf.submitForm({ formValues: values }); })} > <input type="hidden" {...hf.register("token")} /> <input type="password" aria-invalid={hf.register("password").hasError} {...hf.register("password")} /> {hf.register("password").helperText && ( <div>{hf.register("password").helperText}</div> )} <button type="submit">Odeslat</button> </form> ); }

Co je fieldMap a kdy ho použít

fieldMap mapuje lokální názvy polí (klíče ve react-hook-form) na serverové názvy z HATEOAS formuláře.

Tvar je vždy:

type HateoasFieldMap = Record< string, [serverFieldName: string, fieldType: "string" | "integer" | "set"] >;

Použití dává smysl i když jsou názvy stejné (určíš typ a validátory), a hlavně když chceš lokální názvy změnit nebo vnořit:

const fieldMap = { "auth.password": ["password", "string"], token: ["token", "string"], } as const; // pak: hf.register("auth.password")

Automatická tvorba fieldMap z HateoasFormV2

V @alza/hateoas existuje utilita createFieldMapFromForm (také dostupná jako Hateoas.createFieldMapFromForm).

1) Identity mapping (nejčastější)

import { Hateoas } from "@alza/hateoas"; const fieldMap = Hateoas.createFieldMapFromForm(form); const hf = useHateoasForm(form, fieldMap, t, callClientApi);

2) Rename server → local

import { createFieldMapFromForm } from "@alza/hateoas"; const fieldMap = createFieldMapFromForm(form, { rename: { password: "auth.password", }, });

3) Unsupported pole (boolean/set/date…)

Defaultně se unsupported itemTypes přeskočí. Když chceš fail-fast:

const fieldMap = createFieldMapFromForm(form, { unsupported: "throw" });

submitForm a API integrace

Hook si přes AlzaHateoasForm vytáhne url/method/data ze serverového formu a zavolá callClientApi:

type CallClientApi = (args: { url: string; method: string; data?: unknown; }) => Promise<{ isOk: () => boolean; value: { data: unknown } }>;
  • Když response.isOk() vrátí true, můžeš dodat formFromResponse, které z odpovědi vytáhne nový HateoasFormV2. Ten se pak uloží do hooku a provede se reset() + propsání validationError do React Hook Form přes setError.
await hf.submitForm({ formValues: values, formFromResponse: (data) => data.form, });

set (select) – renderování a práce s hodnotou

HATEOAS set se typicky renderuje jako <select> s <option>.

  • pro single-select bývá hodnota v UI string
  • pro multi-select (když maxSize > 1) je hodnota typicky string[]
  • při submitu se set vždy odešle jako array (server tvar)

useHateoasForm.register() vrací kromě RHF props i hateoasField (UI field model z @alza/hateoas), takže máš po ruce options a multiple.

Příklad: single-select

import { useHateoasForm } from "@alza/hateoas-react-hook-form"; import type { HateoasFieldMap, HateoasFormV2 } from "@alza/hateoas"; const fieldMap = { day: ["day", "set"], } as const satisfies HateoasFieldMap; export function Example({ form }: { form: HateoasFormV2 }) { const hf = useHateoasForm(form, fieldMap, t, callClientApi); const day = hf.register("day"); const field = day.hateoasField; if (!field || field.itemType !== "set") return null; return ( <form onSubmit={hf.handleSubmit(async (values) => { await hf.submitForm({ formValues: values }); })} > <select aria-invalid={day.hasError} multiple={field.multiple} {...day}> {field.options.map((o) => ( <option key={o.value} value={o.value} disabled={o.disabled}> {o.label} </option> ))} </select> {day.helperText && <div>{day.helperText}</div>} <button type="submit">Odeslat</button> </form> ); }

Příklad: nastavení hodnoty

// single-select: string hf.setValue("day", "nextday"); // multi-select: string[] hf.setValue("categories", ["Int", "Float"]);

Pozn.: při submitu se day: "nextday" pošle jako day: ["nextday"].

Testování

Balíček má Vitest testy v lib/__tests_.

  • V rootu (Windows/PowerShell policy friendly):

    • cd packages/hateoas-react-hook-form
    • npx vitest run
  • Pokud máš funkční Yarn workspace:

    • yarn workspace @alza/hateoas-react-hook-form test
Last updated on