T
TanStack•2y ago
constant-blue

Form submit help

If my understanding is correct, button elements of type submit that are children of the form.Provider tag should trigger the onSubmit call specified in useForm. I don't know why but I can't seem to trigger this console log...
export default function SigninForm({}) {
const form = useForm({
onSubmit: async (values) => {
console.log(values)
},
defaultValues: {
email: "",
password: "",
}
})
return(
<div className="flex flex-col">
<h1 className="text-3xl font-extrabold text-gray-900 mb-2">Sign in,</h1>
<div className="flex w-full border border-sky-600 mb-8"></div>
<form.Provider>
<SigninField name="email" label="Email" type="email" placeholder="Email" form={form}></SigninField>
<SigninField name="password" label="Password" type="password" placeholder="Password" form={form}>
</SigninField>
<FormExtras></FormExtras>
<Button type="submit" className="bg-sky-600 hover:bg-sky-500">Sign In</Button>
</form.Provider>
</div>
)
}
export default function SigninForm({}) {
const form = useForm({
onSubmit: async (values) => {
console.log(values)
},
defaultValues: {
email: "",
password: "",
}
})
return(
<div className="flex flex-col">
<h1 className="text-3xl font-extrabold text-gray-900 mb-2">Sign in,</h1>
<div className="flex w-full border border-sky-600 mb-8"></div>
<form.Provider>
<SigninField name="email" label="Email" type="email" placeholder="Email" form={form}></SigninField>
<SigninField name="password" label="Password" type="password" placeholder="Password" form={form}>
</SigninField>
<FormExtras></FormExtras>
<Button type="submit" className="bg-sky-600 hover:bg-sky-500">Sign In</Button>
</form.Provider>
</div>
)
}
11 Replies
vicious-gold
vicious-gold•2y ago
button elements of type submit that are children of the form.Provider tag should trigger the onSubmit call
Not quite. We don't listen for events. Instead, you need to use an HTML <form> element to call form.handleSubmit when you run onSubmit:
<form onSubmit={form.handleSubmit}>
<form onSubmit={form.handleSubmit}>
constant-blue
constant-blueOP•2y ago
Perfect that makes sense! Am I maybe misunderstanding then the quick-start example. It appears to exclude a <form> element? how does the button submit work on this example? https://tanstack.com/form/latest/docs/framework/react/quick-start
Quick Start | TanStack Query Docs
The bare minimum to get started with TanStack Form is to create a form and add a field. Keep in mind that this example does not include any validation or error handling... yet. `tsx
vicious-gold
vicious-gold•2y ago
Yup! That's why it listens for "submit". That's a built-in feature of HTML: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/submit
- HTML: HyperText Markup Language | MDN
elements of type submit are rendered as buttons. When the click event occurs (typically because the user clicked the button), the user agent attempts to submit the form to the server.
vicious-gold
vicious-gold•2y ago
TLDR (grabbing an image I made for this): The submit button triggers a submit event that "bubbles" (technical term) up the DOM to the <form> element, which triggers onSubmit:
vicious-gold
vicious-gold•2y ago
No description
constant-blue
constant-blueOP•2y ago
OK perfect! I'll make sure to include the form element. Question from me though, given that it is optional, how do I get the useForm onSubmit function to trigger if not using the <form> tag? would I just add to the button onClick event the onSubmit useForm function?
vicious-gold
vicious-gold•2y ago
You'd follow how our simple example works:
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
void form.handleSubmit();
}}
>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
void form.handleSubmit();
}}
>
constant-blue
constant-blueOP•2y ago
no I understand that part! Thank you very much. Looking at the quick start example though, it does not use a <form> tag. If the form.Provider is not listening for events, and there is no <form> how is the submit button working here?
export default function App() {
const form = useForm({
// Memoize your default values to prevent re-renders
defaultValues: {
fullName: '',
},
onSubmit: async (values) => {
// Do something with form data
console.log(values)
},
})

return (
<div>
<form.Provider>
<div>
<form.Field
name="fullName"
children={(field) => (
<input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
/>
)}
/>
</div>
<button type="submit">Submit</button>
</form.Provider>
</div>
)
}
export default function App() {
const form = useForm({
// Memoize your default values to prevent re-renders
defaultValues: {
fullName: '',
},
onSubmit: async (values) => {
// Do something with form data
console.log(values)
},
})

return (
<div>
<form.Provider>
<div>
<form.Field
name="fullName"
children={(field) => (
<input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
/>
)}
/>
</div>
<button type="submit">Submit</button>
</form.Provider>
</div>
)
}
vicious-gold
vicious-gold•2y ago
Easy: It's not! 😛 Like I said, our docs are really early and I must've borked them when changing an API without realizing it. That said, this might be a good first contribution PR if you'd like to make it to fix this docs error I'd approve 🙂
constant-blue
constant-blueOP•2y ago
I'll submit it tonight--but that answers my question thanks man!
vicious-gold
vicious-gold•2y ago
Sorry for not realizing what you were asking earlier 😅 I appreciate your patience and will look forward to your PR! 🤩

Did you find this page helpful?