Okay.
What we're going to take a look at now is adding our form functionality.
And we need to deal with these inputs.
Now we come across inputs a little bit earlier when we dealt with the search input we created.
Let's just review what we did for that at the time, because we certainly didn't add a package to help
us with this.
But what we did do is we stored the value of the inputs in local states, in the component and inside
our text field.
We had to give it the Onchange functionality so that we could track the value, or react could track
the value as we were typing into the input, and using the Onchange and giving it a value in this way
is referred to as a controlled input.
There's two ways of dealing with inputs and form fields.
In react.
There's the controlled kind that we're looking at here, and there's also the uncontrolled kind where
react is unaware of the state of the input, and we just type directly into the input.
And then when we submit, we can obtain the input value and then use it.
So we're going to use a package that offers both approaches.
The uncontrolled is considered slightly higher performance because react doesn't have to track each
value being typed in.
But it's not a huge difference.
And we don't really want to be doing this onchange scenario for every single input field.
Also, we need to think about submission.
We also need to think about validation.
And if we didn't use a package for this, then our code gets quite significant for what is relatively
straightforward and simple functionality when it comes to react.
So the approach that we're going to take and I'll just go to the documentation for this, a very popular
forms library for react is called react hook form.
And this provides us with a hook that we can use that provides form based functionality and also gives
us easy to use validation as well.
Because whilst we can validate on our API server, and we most definitely will, because that's our
final line of defense.
We'd also want to validate on the client side so we don't waste a network request going up to our API.
If we can catch a validation error on the client side as well.
So this is what we're going to utilize.
And all we need to do is use the npm install react hook form here.
No doubt because I'm on react 19 release candidates, I'm going to need to use the legacy dependency
switch as well.
Something else that we're going to use with this, though, at the same time, is this does come with
basic validation, but we can also use a validation library to help us validate our form.
And the one that we're going to utilize is called Zod.
And this gives us some additional features as well when it comes to TypeScript.
So we're going to take advantage of both of those.
And we'll go and set this up.
So I'll just copy that npm install into my clipboard.
And we'll go back to our terminal and let's clean up some of what's going on inside here.
I'll pick the third tab that we're using to install stuff.
So we need react hook form.
We also need Zod.
And when we're using a third party validation library like Zod, we also need to use at hook form forward
slash resolvers so that we can utilize this inside our form.
So I'll press return and once again fail of course, because I'm on the release candidate of react 19.
So I'm going to add the switch legacy peer deps.
And like I've mentioned before, if you want a stable version of react 19 it's been released, then
this shouldn't be necessary.
But if you do see that error then this is what we need to add.
So let's take a look at how we use this.
Now first of all we're going to use Zod and we're going to create a schema.
I'll just close everything down at the top.
And we're going to create a schema for our login form.
And we'll do that inside lib will create a folder, a new folder, and I'll call it schemas.
And inside this schemas folder I'm going to create a new file.
And it's going to be called login schema dot ts.
And the idea of this is we create a schema that our form can use.
And this uses that to validate against our form.
So we're going to export const call it login schema equals.
And we need z that we get from Zod.
So make sure you've got the import z from Zod.
And then we can use z dot object for our form fields.
So we open up parentheses then curly brackets.
And we specify the fields that we wish to use this for validation for.
So the first one is going to be email.
And we'll use z dot string add parentheses.
And then we can chain on a second validator and make that email.
So we're just validating that this is a string.
And it's a type of email.
And if it's not an email, a valid email address, then we're going to get the appropriate error that
we can use to lend display inside our form.
And we'll also specify the password as the other field.
This is also going to be a type of string.
And we'll add an additional validator on here.
We'll just check the minimum length and we'll just specify six as its minimum.
And if we want to give this a custom message then we can open curly brackets after the comma and specify
a message and say password must be at least six characters.
Now we could go further and supply all of the different validators for a complex password on a client
side.
But I'm going to demonstrate using a combination of both, just to make sure that our API validation
is working, as well as our client side validation as well.
So now we have this in place.
Let's open up our login form once again.
And up at the top here we're going to use react hook form.
So just below the function login form we'll use const open curly brackets.
And then we're going to use a hook that we get from react hook form called use form.
So we'll bring that in.
And then the functionality that we're going to use from this we're going to use the register function.
This is how we register our different inputs into react hook form.
We're also going to bring in the handle submit when we wish to submit our form.
Then this is going to take the values that have been registered and entered into our form fields.
And then we can add the logic to submit this to our server.
And we can also get the form states and inside curly brackets.
Here we have things like whether or not the form is dirty, if it's loading, if it's an asynchronous
request that we're making to our API server, then this automatically enables a pending state and we
can track the loading of an input or form submission.
But for the time being, we're just going to use the errors that we get from this.
So below this we'll create an Onsubmit method and say const Onsubmit equals.
And we'll take in the data which is going to be a type of.
And one of the other things that the login schema we can do with this is we can generate a type using
Zod for our login schema.
And the way that that works is we'll export a type back in our login schema and we'll call it login
schema.
And we'll set it equal to z dot infer.
And then we can use typeof and specify login schema.
And that will give us the type that we can use inside our form as well.
So it's quite useful this Zod functionality.
So back to our login form we'll specify data as the argument.
And this is going to be a type of login schema what we've just created.
And then we'll add the arrow open curly brackets.
And for the time being, we're just going to console.log the data.
So let's go down to our form and see how we can use it.
So our box with the component where it's specified as form.
Then we can use our Onsubmit functionality inside here.
So just below the component form I'll use the Onsubmit.
And then we can use the handle submit we get from react hook form that we brought in.
And we can use this to call our Onsubmit function.
Now we're getting an error here because it doesn't match the type that we've specified as login schema.
So we also need to give our use form a type as well.
If we come back over here then we also need to specify the login schema here so it knows what fields
we have available.
And that should resolve the error we have with the Onsubmit.
So let's go down and deal with our different text fields.
So inside here, in order to use the register that we brought in from react hook form we'll use dot
dot dot register.
And then in parentheses we give our input a name.
And in this case we've got a choice of email or password.
So we'll use this for email.
And we won't use the word validation just yet.
We'll just use the simpler out of the box react hook form validation.
And in curly brackets after a comma I'll just specify required and we'll just say email is required.
So it's not going to validate that this is an email address yet.
We'll need to use odd for that.
But for the short term we'll just use the simpler validation errors we get from react hook form.
We'll then use the error property that we have available with the text field.
And we'll set this equal to.
And we just want to know if there is an error for this particular property.
It takes a boolean.
So we'll use double exclamation mark and then errors dot email.
Now the email property inside the errors is a field error, but we want to convert this into a boolean
so it satisfies what the error here is looking for.
And if we use double exclamation mark, that effectively casts this into a boolean.
So if errors dot email has something inside it that will return true.
And that's what we set our error to.
And we can also display some helper text in our inputs as well.
And we'll specify errors dot email dot message as the helper text there.
So then we just need to do a very similar thing for our password.
So I'm just going to copy this and paste it into our password field.
I'll change email to password and say that password is required.
And just update this to password and also the helper text as well.
And that will suffice.
But for a button we also need to give this a type so that when we do click on it, it calls the form
and submit method.
So we'll give this a type equal to submit.
And now we're in a position to test obviously what we'd like to see.
When we do enter some details and click the button.
We'd like to see the data the input values outputs into our console.
So that's what we're aiming for here.
And I'll just refresh the page, make sure everything is fine.
And I can see that the autofocus puts me on the email.
When I do refresh the page, I'll just open up the Chrome DevTools, make sure there's no warnings or
anything nasty inside there, and I'll just put in.
Oh, it appears we do have an issue, or at least I have an issue.
And this is telling me that I have something nasty going on with one of my chrome extensions.
Now, this is not an application problem as far as I can tell, but it does appear there's an issue
with my Chrome extensions not related to our code.
So I'm just going to pause the video, see what this is all about, and then come back once I've taken
a look.
So it was indeed a problematic extension.
In this case it was the iCloud passwords, which I have just enabled disabled.
So I can demonstrate this and let's go back.
And if I just type in test into the email field and test into the password field and click sign in.
Then we get the output into our Chrome DevTools there.
If I take out the password, then we can see that the password is required and the same for the email
as well.
But it's not asking us for a valid email.
And if I do type in, then I'm not going to meet the requirements of our API for sure.
But it does prove that the form functionality is working and our basic validation is working as well
at the moment.
So now we have this functionality enabled.
In the next lesson, we'll take a closer look at validation.