ilokesto

Build a login form

Start by keeping the form instance outside the component so it is not recreated on every render. Add values that match the request payload, not the visual layout. Then bind fields with the framework adapter.

const form = new CreateForm({
  initialValues: { email: '', password: '', remember: false },
  schema: loginSchema,
  validateOn: ['blur', 'submit'],
});

function Login() {
  const { form: controller, useField, useRegister, useFormState } = useForm(form);
  const email = useField({ name: 'email', schema: emailSchema });
  const password = useRegister({ name: 'password', type: 'password' });
  const remember = useRegister({ name: 'remember', type: 'checkbox' });
  const state = useFormState();

  return <form onSubmit={(event) => { event.preventDefault(); void controller.submit(signIn); }} />;
}

Use field-local schema for immediate field messages when it is more specific than the form-level schema. Use submit for the final gate. After a successful sign in, call reset(controller.getValues()) only if the current values should become the new clean baseline.

Checklist

Before shipping, verify that labels and accessibility attributes live in your markup, schema errors are shown near fields and summarized when useful, tuple paths are used for nested values, and array commands are the only way dynamic list structure changes. This keeps the form predictable even as product requirements grow.

On this page