Gestiona valores de formulario con estado React.
Gestiona los valores en React y léelos al guardar. TextField también admite name y participa en FormData. Toggle, Picker y Slider no emiten valores de formulario nativos: lee sus valores desde el estado.
Este patrón funciona con texto, booleanos, opciones y números. Usa el mismo estado inicial en el servidor y el cliente:
import { useState } from "react"
import { Button, Picker, Slider, TextField, Toggle } from "@liquidify/react"
import "@liquidify/react/styles.css"
export function AccountForm() {
const [name, setName] = useState("")
const [notify, setNotify] = useState(true)
const [plan, setPlan] = useState("free")
const [volume, setVolume] = useState(0.5)
const save = () => console.log({ name, notify, plan, volume })
return (
<form onSubmit={(event) => event.preventDefault()}>
<label htmlFor="account-name">Display name</label>
<TextField
id="account-name"
name="name"
value={name}
onChange={setName}
placeholder="Ada Lovelace"
/>
<Toggle
aria-label="Email notifications"
checked={notify}
onChange={setNotify}
/>
<Picker
aria-label="Plan"
items={[
{ value: "free", label: "Free" },
{ value: "pro", label: "Pro" },
]}
value={plan}
onChange={setPlan}
/>
<Slider
aria-label="Alert volume"
value={volume}
onChange={setVolume}
min={0}
max={1}
step={0.1}
/>
<Button variant="borderedProminent" onPress={save}>
Guardar
</Button>
</form>
)
}Cada onChange entrega directamente un valor tipado: string para TextField y Picker, boolean para Toggle, y number para Slider. No necesitas extraerlo de un evento.
Button usa <button type="button">, por lo que debes ejecutar el guardado desde onPress.
TextField transmite name al input nativo. Puedes leerlo con FormData sin estado controlado:
import { useRef } from "react"
import { Button, TextField } from "@liquidify/react"
export function ContactForm() {
const formRef = useRef<HTMLFormElement>(null)
const send = () => {
if (!formRef.current) return
const data = new FormData(formRef.current)
console.log(data.get("email"))
}
return (
<form ref={formRef} onSubmit={(event) => event.preventDefault()}>
<label htmlFor="contact-email">Email</label>
<TextField
id="contact-email"
name="email"
inputMode="email"
autoComplete="email"
/>
<Button variant="borderedProminent" onPress={send}>
Send
</Button>
</form>
)
}Combina esos valores con el estado de Toggle, Picker y Slider, que no participan en FormData.
Form y Form.Section agrupan los controles visualmente. No gestionan valores ni estado; el elemento <form> sigue siendo responsable del envío:
import { Form, TextField, Toggle } from "@liquidify/react"
export function GroupedForm() {
return (
<form onSubmit={(event) => event.preventDefault()}>
<Form>
<Form.Section title="Profile">
<label htmlFor="grouped-name">Nombre</label>
<TextField id="grouped-name" name="name" />
<Toggle aria-label="Public profile" defaultChecked />
</Form.Section>
</Form>
</form>
)
}Asocia las etiquetas visibles mediante htmlFor e id. Usa aria-label para controles sin texto visible. Coloca la validación junto al campo y conéctala mediante la API documentada. Consulta Accesibilidad.