Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type a Form component with onSubmit?

I've got my own Form component which I want to keep separated from the Parent Component.

const Form: React.FC<any> = ({ children, handleFormSubmit }) => (
  <form onSubmit={handleFormSubmit}>{children}</form>
);

Parent Component

const ParentComponent = () => {
...

const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    publishReview(review).then(() => setReview(initialReviewState));
  };

return (
 <Form onSubmit={handleFormSubmit}>
...
</Form>
)}

I thought handleFormSubmit would get the types from its declaration const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>).

But it doesn't

I've tried to build an interface and even with an any type:

interface FormProps {
  handleFormSubmit: any
}
const Form: React.FC<FormProps>= ({ children, handleFormSubmit }) => (
  <form onSubmit={handleFormSubmit}>{children}</form>
);

But it gave the below error:

const Form: React.FunctionComponent<FormProps>
Type '{ children: Element; onSubmit: (event: FormEvent<HTMLFormElement>) => void; }' is not assignable to type 'IntrinsicAttributes & FormProps & { children?: ReactNode; }'.
  Property 'onSubmit' does not exist on type 'IntrinsicAttributes & FormProps & { children?: ReactNode; }'.
like image 322
SixtyEight Avatar asked May 27 '19 08:05

SixtyEight


People also ask

How does Onsubmit work in HTML?

The onsubmit event is an event that occurs when you try to submit a form. You can put your form validation against this event type. The following example shows how to use onsubmit. Here we are calling a validate() function before submitting a form data to the web server.

Why Onsubmit is not being called?

The onsubmit handler is not called, because the form cannot be submitted by any normal means, i.e. the submit event cannot be caused. There is only one submit control, and it is declared as disabled.

How do I add onsubmit to a form component?

Either call <Form handleFormSubmit= {handleFormSubmit}> or change the props of the Form component so that the prop is named onSubmit. Here's how it should look if you rename the prop to onSubmit and give it a proper type instead of any.

How do I change the name of the onsubmit prop?

Your Form component takes a prop named handleFormSubmit, but you are calling it with a prop named onSubmit instead. You need to change the name in one of those places so that they both match. Either call <Form handleFormSubmit= {handleFormSubmit}> or change the props of the Form component so that the prop is named onSubmit.

What is onsubmit in JavaScript?

Examples The JavaScript onsubmit is one of the event handling function used for performing the operations in web based applications.

How to prevent the page from reloading on the form onsubmit?

You can do other things like sending a request to an API as well. Note that in order to prevent the page from reloading on the form onSubmit event, we need to call: What is the type of event? Let’s dive into the code. 1. Create a new React project with this command: You can replace react_ts_form with whatever name you want. 2.


2 Answers

This worked for me. Just guessing based on your guess. Thanks!

handlePostForm = (e: React.FormEvent) => {
like image 89
Bday Avatar answered Oct 24 '22 03:10

Bday


You would need to specify the type of the form elements. Let's say for example in your form you have an input with id yourInputName:

<form onSubmit={handleSubmit}>
  <div>
    <label htmlFor="yourInputName">Username:</label>
    <input id="yourInputName" type="text" />
  </div>
  <button type="submit">Submit</button>
</form>

In your handleSubmit, you would need to specify the type of the event.currentTarget. A form tag has a type of HTMLFormElement with a property elements, which are a type of HTMLFormControlsCollection, but we can override that to tell TS what our input is. Create an interface which extends the HTMLFormControlsCollection, specify the type of your field and then use the custom interface to override the elements property in the HTMLFormElement.

interface FormElements extends HTMLFormControlsCollection {
    yourInputName: HTMLInputElement
}

interface YourFormElement extends HTMLFormElement {
   readonly elements: FormElements
}

Then you pass that new type to your handling function

const handleFormSubmit = (e: React.FormEvent<YourFormElement>) => {}

You can now access the value of your field and typescript will know what it is

const handleFormSubmit = (e: React.FormEvent<YourFormElement>) => {
    e.preventDefault();
    console.log(e.currentTarget.elements.yourInputName.value)
}

If you hover on value, TS should show you a message that the data type is HTMLInputElement.value: string, just as you have specified in your FormElements interface.

like image 16
Ivo Avatar answered Oct 24 '22 02:10

Ivo