In this lesson we'll take a look at how to make a basic form with React. We'll see how to use the onSubmit
event to prevent the default submit behavior of forms with React and then how to use that event to get the values from the form. We'll also see how you can use the React ref
prop to get the value of form elements as well.
Instructor: [00:00] We'll start by making a new class called nameForm, and that extends React.Component. Then this'll have a render method that will return a form element. Inside of this form, we'll have a label. Inside of this label, we'll have a name and an input with a type of text.
[00:21] Then we'll have a button with a type of submit, and the text submit. We'll go down here, and we'll render that nameForm. Now, we can submit a name, Sarah. That's actually going to do a full page refresh, so to prevent that, we need to prevent the default behavior.
[00:39] Let's go ahead and add an onSubmit event handler to this. We'll say this.handleSubmit, and then we'll add that as a class property here. This is going to get us our event. We'll say event.preventDefault. Now, if we say hi there and submit, then we're not going to get that default behavior, and we can do our own behavior.
[01:02] If we want to get the value that we type in the input to send in an Ajax request or something, there are a couple ways that we can do that. Let's first console log our target with event.target. If we pop open our developer tools, say hi, and submit, we're going to get the form is the target.
[01:21] We can see a bunch of properties on this form. One of those is referencing our input. That input has a value property that we can find right down here. We can get our value that way. We could say console log event.target at zero.value.
[01:40] Then if we say hello, and we're going to get that hello there. Another thing we could do is add a name prop on our input, and call this username. With that, we can say hello. On our form, we can look at the elements property, and get the username. That will be a reference to our input as well.
[02:01] We'll console log event.target.elements.username.value, and now we can get the value of our input in either way, this one being a little bit more direct. Then finally, the most direct way that we could do is using the ref prop.
[02:20] Here, we'd say the node is going to be this.inputNode equals the node. Then in our handler here, we'll say console log this.inputNode.value. Then we can say hi there, and we're going to get hi there for all three of these.
[02:40] Now, these first two methods of getting the value of the input are actually just regular HTML. If you have an event handler on a form using just raw DOM APIs, then you can get the target from the event, get the first element from this form, and get the value there.
[03:00] You can also put the name attribute on your input, and then use the elements from the form to get the item by its name and get the value. Then this ref prop is definitely just a React thing. It makes things a little bit more direct, because here, we see we're assigning the input node, and then we're referencing that input node to get the value.
[03:22] However you do it, all three of these work just as well. I like using the ref, because it makes things a little bit more explicit, but if you have a really big form, using something like the name attributes works really nicely, too, so you don't have to have a whole bunch of refs to keep track of.
Hi Hozefa!
So you could do that. But there is a better (more declarative) way to accomplish the same thing. You can use the defaultValue
prop when rendering: <input defaultValue="hello world" />
.
Also, there's a concept of controlling the input value which you can see in a future lesson in this course :)
Sure I can use defaultValue
. Actually the problem I have is that, there is a page with a pretty long form(internal tool) that I am working on. So I am using controlled component for it. But that in turn causes me to have pretty big state
for that component.
So I was wondering if there is another way to achieve this, without having to put every form field value in state
?
So, if you can use defaultValue
then I suggest you do that. It's much simpler. If that's not an option for some reason, then there's not really any option to avoid having a lot of stuff in state
(and it's not really a problem if what you're putting into state is really stateful).
Just out of curiosity... when I console.log(event.target), I get the html if that makes sense, but when I log it like you did, console.log({target:event.target}) I get a more detailed response. Is there any reason for this?
Alex,
That's a feature of the browser developer tools. It's kind of neat, but also a little annoying. That's why I did the object form. You can also do: console.dir(event.target)
and that will show you the object form as well.
Using
refs
would we be able to add a value to the input field. Say for example I have some resource I am editing through a form and need to prefill the input fields with existing values.