React-hook-form, the best way to do form validation | JavaScript JOB READY Free Course (2025)

Phil Choi builds a validated React form with react-hook-form, Tailwind, and Firebase. He creates a reusable FormInput component, sets up validation rules for email and password with regex, and adds a show-password toggle using useReducer.
Chapters
So in front end development, before you send like some data to the back end, you should do some validation inside of the front end to make sure the data is okay. So today I kind of want to go over a react hook form and just make a simple like sign up form or an edit profile form. It could either be. It could be either one and you know, ready the payload. Make sure that people are putting in the right input values, the right lengths, the right, you know, whatever it is that it may be right, like.
The.
Right, like making sure like the. It's. If it's a required value, the value is there. So let's get started. So.
Cool.
So I opened up. Okay, so. And I know we did like lesson 1, 2, 3, 4, 5, 6 and they're all like um, what it's all like in the kit right now. So if you just pull it should be there. But the one thing you have to do is get your own Firebase keys to get any of these projects working. And today's the sixth one, it's going to be. So honestly, like last time we did the chat one and the one before we did Firebase authentication, the one before we did. What do we do?
I don't remember. What do we do?
Strict mode app tsx. Oh and then we did some API calling in there too. So I think from lesson three, four and five we'll be able to use all of these kind of things together in like the finale final project. And this one will be another piece of that too.
So.
Lesson six, we'll have some kind of, we'll make some kind of form with Daisy ui a tailwind. And I set up, I set up the project already. So right now I put it in the readme. Making a form with validation using reactive form. Reactive form is a nice hook. I'll go to the website real quick. But it's a hook to kind of add some kind of controllers to your input inputs or whatever kind of like form inputs you use to kind of like check the values and you don't need to make like another piece of state or a reducer and react hook form will handle it all for you and it'll link it with like one control variable that comes off of the reactive form and then you put that in here for in the pieces you want to connect to and it will validate it. So we need. So the three main projects. I'll make it a little bit bigger. I know that I have a issue with making this too small sometimes. So is this an okay size? If you guys can press like one in the chat. It'd be pretty cool. Okay.
All right. Okay, thank you.
So we have packages. The main packages we're using are Firebase. So that's from lesson four and five. And React took form and Axios. And React took form is what. What I just explained for about the validations and all that kind of stuff. And Axios is just a little wrapper for HTTP. It helps make like HTTP requests a little bit easier. And then for our dev dependencies, I'm using Tailwind css Post css. These are just tailwind setups, Auto prefixer and then Daisy UI and then dot M for environment variables. Your product is ever not working. It's probably because I did not put the environment file inside of the git. I put in my git ignore. It's because it's all my API keys and stuff. So you guys will need to get that yourselves. It's just here you go to the project overview, add an app, and you should be able to get access to the Firebase keys also.
Let me see here.
So what I did so far, I put up the setup tailwind like instructions and the setup phase UI instructions in the readme. And I already did it. So you just run like mpx tailwind CSS init and it'll pop out these files. Post CSS config js and tailwind config js. And then you just have to edit it for like to use with Tailwind. And then the plugin that we want to use is azui. So those are the. That's all you have to do. It's pretty simple setup. And then you'll have access to all these components. Daisy ui and I'll go over here.
I'll make this bigger too. There we go.
And then you get like have these components from Daisy ui and you know, you have an accordion, an artboard alert carousel. I'll just show you for a second. Like let's say I want to use this carousel, I guess, or snap to.
Center where it's going.
Carousel of full width items. Vertical carousel.
I don't know why this isn't working. Yeah.
Carousel of half items.
Oh, there you go. Gotta scroll sideways.
Full bleed carousel. Carousel indicator buttons. Maybe like that's something that we would want to use in our home page. You just grab this jsx, copy it and then let's just. Let's just see if it works in our project. Because it's set up. I'm just gonna delete all these guys. This is the boilerplate Code from byte. You can remove all this stuff. It's not that important for us. And then just turn my GitHub copilot off. Disable completions.
All right, Return that. Oops. Div container. All right, See how that looks?
Now we have some kind of carousel here. Pretty cool. And you guys can just kind of like use whatever you want from Daisy. Why? It's pretty. It's a time saver. I mean, I wouldn't say use it like without learning the CSS first or tailwind, but it. It helps you save some time in the end. So let's go with that. And I think I do want to delete all this CSS here too. And app css.
We don't need that. And yeah, I can just delete that guy.
And then in the index css, I'm pretty sure I can delete all this too.
Let's delete that. All right, cool. And I will turn all this off. Cool.
So here. Hello world. Now we see hello world on here. If I ever. Oh, and one other thing that I did was in the main tsx, I initialized the Firebase already. So this is my firebase keys. These are the variables in my environment file. And then I initialize Firebase inside of this. Inside of the main tsx and I initialized get auth. So the AUTH module, the Firestore module is our DB and get storage for like uploading a photo. So they're all working like in the console here. So I'll have access to them and I'll just import them straight away from this file. Meaning, like I won't have to reinitialize it later. I'll just import the DB and the Auth and the storage for main TSX inside of my pages. So now we have hello World here.
If we look here, we have inspect the container.
The container has some kind of max width 768. It has some stuff for us from. What is it called? Tailwind. So let's. Let's go back to our Daisy.
And.
Let'S just make a.
Let's make a little form or let's see.
File input. No, I don't need a text input. There we go. So I'll just copy paste this guy. Our text input with label inside. Sounds good.
Or.
Sounds pretty good. I used the corner one earlier, but.
Let'S go with this one.
I will just stick this guy in here. Let's see what we get. All right, so we have some kind of. Some kind of a thing here, right? So.
Cool. All right, now let's go here and it's in the label tag. All right.
And then one thing we have we will do is we'll use React. Click Form. So we'll do import, import, use form from React or no, no, react, hook form. And that's what's going to tie these inputs together and that's how we're going to get the values. So very simply you can just put like control, get. Get values. Let's go through the documentation. Handle submit equals use form. And then here you can set some values. But give me a second because I.
Will look up the.
Reactive form is a very popular NPM package. People are using it with React native for mobile apps. They're using it for React web. And it's, it's just an easy way to kind of. There's many different validation stuff. You can roll out your own with regular expressions and. Or pattern in inside of the input or. And you guys can see how popular it is. It has like 6 million downloads. I used to use Formic because that's like what a tutorial taught me before and this one's pretty good. But it. You need some boilerplate code, as in like a wrapper or like the formic context of your whole app. And I thought Reactive form was better because it does stuff. You don't need to wrap your app with any kind of wrap or anything like that. So Reactive form seems to be pretty good and it helps with. You don't have to put like, like on change, set a state like every single time because reactive form handles all that for you. So let's just get started. So this guy. You have an input. You have register. I'd like to use the.
Just looking here on submit, on submit and then candle submit.
Like okay, I see what's going on. All right, so yeah, register, handle, submit. And you could do it this way where you just register stuff. And that's very simple. We can, we can try that out. Oh, register. But I do not use it this way. So I'll just test it out. You can say it says register and then let's just say this is going to be the username and seems like this one will be the email.
Register, email.
And I'll get rid of this input and I will change this one to.
Something like this and we'll do password, register, password and just want to get rid of that and like this. And then let's make one more called confirm password.
And I'll close this file tree right now. So right now we should have. We registered what, four, four inputs Here and I'll just add a button as well so we can actually see it.
Button Submit and we'll say on press.
Or no, no, on click.
That one takes the handle submit and.
That takes a callback straight.
I think you could do like data. Oops. Pretty sure that would work.
Data gets the field values from there. All right, if you guys ever want to wonder how do you change like the title of the thing, title of the app and stuff so this fight react doesn't work. Stay there.
Think it's in the public or.
Or the index HTML. We could just change it to.
Form validation. There you go.
And it'll change. And if you want to change like the.
What is this called?
Favicon. You guys just need. We would need to get another svg.
But have one? Yeah, I have one. It's just.
Just use this one for a second.
Set of public.
Call it messenger.
And we can actually do messenger. What should change.
So that's how you change this title stuff as well. It wasn't that big of a deal, but thought maybe, if you're wondering, we.
Can figure it out. All right, so let me see here.
Main tsx app, dsx.
Do want some padding. Let's do P4. All right, cool.
And then on these guys, I just.
Want my two whoops. If that works. All right.
Now they're a little bit away from each other and I'll just.
Put a class name on here called button. I think that'll make a little bit.
Little bit prettier now.
Okay, so let's go here in the console.
Now you see that they're all registered with the confirmed password. And I can get the values in here, right? That's kind of how it works right. Now let's go look at the documentation a bit more. And inside of here you can actually the second argument and register. You can also put like required.
So it's required.
And then you put a message like username is required.
And now I refresh the page. It's on the left side.
I submit.
Whoops.
One second. It would not submit because it's telling us that something's wrong. And now it'll submit. So the way you get that error to pop up is flip through here a little bit.
Not quite sure, but I do know.
I want to use the controller. So I've never used it this way before. So give me a second. That's why you do not use it this way, because we should make our own like controller and be able to control the errors in there. And I'll show you how to do that. So for me I like to use this thing called controller and I put it in the complete, putting the complete components here. We'll just kind of look through the documentation and figure it out together. So we'll get controller and then I'll make my own input here called like function form input and let's figure that out.
What are we returning here?
Elements.
And.
All right, so if we look through the documentation, I see that there's a controller here and it can take a name, it can take a control which I'm used to using and then the render, which is the component that we want to render there. So and render has things like field and I think it has something called errors or like field error. Let me look at it real quick. So I did something very similar. It has a name, a control, the rules that you want your validation to have and then your render and then your field state has. Okay, it takes a field and has a field state and the field state has something called error. So when error is actually not undefined, you can show your error message. So let's get started. So I usually put in a different file, but I'll put in one file now and then we'll move it over.
Shortly.
So controller will be a self closing tag and this one will take something called name which will be a string and that it's not going to be optional. And if you're wondering what this is, this is an Interface. This is TypeScript and it's a way you can type your props. You could either use type or interface. But I like to use interface when I know it's going to be an object and for my components and I just name it I form input because it's interface form input. That's what people used to do in TypeScript a long time ago. But now you will kind of see people just put form, input, interface but.
Too much typing for me.
So I form input name, it'll take the control and that's going to be. It comes from, it comes from the control and then I think it comes from field value. And that's how you do it on TypeScript. We'll take a look because I got it done earlier and then maybe this one is any for now, but we'll fix that in a second. And then what's another one that it needs? It needs.
Rules.
So the rules will be thing here, this type here is.
Interesting.
So the rules. I got this type from some documentation. So field values string. And the string is what we're going to pass. And then I just got this type because I kept on passing the wrong type and I hovered over it and it gave me this type. Like if I put.
On think I.
Put rules and I just put like object here or something. And then I try to put like rules equals object. This, it'll tell me, it'll give me this. What the rules are is a type already. So I think I just copied this one. Omit register options. So omit is a typescript generic function. I think it's a generic function, but you take. You take some kind of type that you already want and then omit will be like, okay, it's everything that this type is except for disabled value as, number value as date instead of set value as. So TypeScript has two different generic functions or generics, generics that they use omit and pick. And pick is the opposite of omit. Right? It's hey, there's this type and I'm picking just like a couple values from there. Omit is, hey, I want to use everything but omit these. These types. So that's something kind of interesting as well.
So.
If you ever want to get like super into Typescript, Me personally, I don't really.
I like Typescript personally a little bit.
But TypeScript is really good in the front end, but in the back end, I feel like I don't use TypeScript that much.
So that's something I'd like to say. So.
And we got the rules, and maybe inside of another place we can pass in type, which could be text.
Whoops. It could be text or password.
And let me think, what else do you think we're going to need? Maybe placeholder.
That's going to be a spring.
And that one looks good to me for now. For now.
So.
Let'S say I'm going to say this is iform input and this one.
Takes a name, control.
Rules, type and placeholder. And maybe we can just put it as optional.
That'd be good. All right. Yeah, placeholder can be optional too.
But we're always going to need rules. We're always going to need a control, and we're always going to need a.
Name to match it. So we look at here, we'll say.
Name and the name will equal the name prop that we're sending this form input.
The rules will be the rules.
Most important thing is control.
Roll.
And then this one will take the render. And then the off the render, you're going to have something called field.
And I'm just gonna go back up field and.
Field State.
I just want this. All right, so field and field state.
And off of the field state, I'm destructuring the error. So in the render for now, I'll just put a H1 render this here.
Return, and. Okay.
And we're not using these yet, but I just want to show you that we can use this form input now and it'll just be the. The what we're rendering. It's just, it's. It's very simple. It's just rendering the JSX that we're putting in here, and then we just spread the field inside. So that's. That's all we're doing. That's what's controlling, like the whole. Because we're passing control into the parent, which is the controller. So through there it passes field and it.
It's.
We're spreading the field into the input.
So let's do that real quick, actually. So input.
Then the first thing we'll do is we'll just spread field into here. And then from the top, pass placeholder and the type. I'll pass. I'll pass the type. And type is undefined because we said it's optional. It'll be text. So. And then we just make it a div to make it like block.
And then on the bottom here, I.
Want it out of the div.
I think so.
And then from there, if the error is true, we want to show the error. Error message.
One second. Okay.
Error message. So let's. Let's get this working. So you're not using form yet. So instead of the inputs that we put here, right. We can actually put the. We can actually put the form inputs.
So let's get that done.
And all these have class name of grow. So let's actually pass class name too.
Which can actually be optional.
String. And then in that render from the.
Input, just trying to think something, we'll.
Say class name equals. And we'll say.
Grow.
We'll put a space and then plus.
That'S the smartest way to do this. Last name.
So if this is a string, and.
If not, it'll just be an empty string. Undefined. Last name is undefined. We'll just do an empty string. I think that should work.
All right. And from here now we're using the control. So I'll just take this guy out and I'll put the form input instead.
I wonder why people drop that inside of here.
We'll say we don't need the class name anymore. Placeholder equals.
Let's just say user.
And then Control Equal to control.
What?
And then the rules will equal. Let's just say like required. That could be like user name is required.
And.
Let'S go like min will be min. Or is it min length?
Min.
Min length. Is it min length or the min? I put it down here somewhere. React form min max validation. This. It's, it's. It's min length and max length. All right, so we'll say.
Min length is.
Length. I'll just look over here. M tsx. Add some rules here.
Required. Required.
Have a min length. Min. One second.
Thought I had some min stuff.
I guess I did not. All right.
Min max.
Keep it at this for a second. One second. Min error message. React.
How to show min.
Max error.
I think your screen share disappeared.
What?
Your screen share disappeared.
My screen share disappeared?
Yeah.
All right, one second. Is saying I am sharing.
Oh, really? Yeah.
Like I see it online. Oh, here it is.
So that for you.
Okay, there's a max.
Must be less than Max is 50 is allowed.
Okay, so, all right, here we are.
So you can actually say like the min. And then value is. Let's say the value is two.
Can we, can we reshare?
Sorry.
So I think the. On the. It's not working on my screen.
Real quick.
Just. Just wanted to make sure the recording is okay.
You know, I stopped share. Yeah, share here.
Yeah, it's working now. Okay. All right, Sorry about that, guys.
Yep.
And we put a message and we could say minimum username needs to be.
At least two characters.
And then for like max, we can do value.
Maybe like 25 and then message username and not be more than 25. All right, so let's.
And then form input name is missing. So name is a very important one.
Name will equal username.
And let me check here now.
So I try to submit, it's going.
To say username is required. You guys see that we do want to make it a little bit more defined. So maybe in here we could put.
A style equals font size like 14, maybe like smaller 13 color red. Like this.
What is red? F00.
Yes.
All right, so username is required. If I type and I try to.
Submit here, it'll should have given me that warning error. Right?
Obviously only the username is required is showing up, but the min and the max is not showing up.
So let me figure that out. Maybe it's min length maximum. There you go. Okay.
And username needs to be at least two characters.
They'll go away. And if I go like here and.
I'll go username Cannot be more than.
25 characters and it won't let me submit. At this point, you don't see the log, right?
And then if I did like this.
You can see the log here.
But now we're getting some error components changing an uncontrolled input. So in the used form, we need to actually give it some value first because it's telling us this is likely happening because the changing from undefined to a defined value. So maybe we can just put an empty value in the beginning. Why is this?
Because we need to actually put the type. Yes, Zod would help us a lot here. But okay, it's going to be a string.
What else do we have in the email?
It's going to be a string password. It's going to be a string confirm password empty screen. Now we're getting some kind of error. Let me see here. I just put it here. No, wait.
Async default values username string email password String Confirm password 10 or more. And username does not exist in the partial mode on change.
Wait, wait, wait.
We're going to have to go back.
To the app tsx.
Oh, sorry. We got to put default values.
Sorry.
And then we don't need to actually pass it back.
Type here. All right, now am I doing it correctly.
Here?
Default values username. Why is it give me such password?
Email.
Password confirm password. So now I think our control thing will go away. So there you go.
Try to submit username cannot be more than 25 characters. And then now it's watching. So there's a lot of cool stuff from reactech form. And then in the end, if you ever want to get the values.
What.
Should I show you guys first, in reactive form, I use watch a lot as well.
So watch.
And then you could actually say watch. And then you could treat it like kind of like a state. So you can say like cons watched.
Username val you can say watch username. Then you can say watch on because.
You know which types it has right from the control and from the default values and stuff.
So you can say watch and I.
Want to watch the username. And then now you can couple that with something like let's say import use effect. And then you can add the use effect inside of here and you could.
Be like use effect.
And then as a dependency, put watched username. And then you can put console log.
Watchdogname equals equals watched username.
And then now in the log, anytime this guy changes, it'll observe. That's pretty cool. But the error message will not happen until you're in the submitted state. So so far, are there any questions? I know I'm going pretty fast, but I. I do want to get the.
Form done before we finish today and.
Seems like the group got a little bit smaller.
I think it's okay.
All right, so we do have the username all connected now and now we can kind of get the value and if you did not want to use the data callback here and now I can just say like console log values. I just want to show you guys one thing. So now it console logs values but let's just say I did async and I did Const. Vals equals get values do an 8 weight on it. Oh no up but then you do a console log. Vals equals vals instead of this values you can actually get the values from the. And that's like exactly like what it's using. So you can. You always have access to the values through a function and you always have access to like many things like watch, handle, submit, register and all this kind of stuff. And register we're not going to use anymore. So now let's replace all the inputs with what we made and I think that'll make it a little bit better. So we'll just copy paste this and we'll go to our input here and.
We'Ll do this and we'll say the.
Email is required min length, max length. I don't think email should really have a max length and min length. Email is has to be at least like. I don't, I don't think it should.
Have been linked either but I think.
There'S some validation react hook form email validation. So form validation with reactive form advanced usage. So let's check this out. I think there's some regex that we can do. Regex is like regular expressions I did earlier too.
So let's just find it form pattern and there's something called pattern and if.
It doesn't match this regex then it's going to tell you that it's invalid email address. And that's kind of what we want. So and we'll do this on email. The placeholder will be guestmail.com control that'll be good. Email is going to be required and.
I think now let's check if this is working. So refresh try to submit.
Email is required. So empty string is still like a, like a not good value inside of reactive form if that's what you're wondering. And, and now if I try to put like it's going to say invalid Email address. But if I say hello@babyby.com, it should go away. So that's, that's how we're going to validate it. Now the password. Password. Let's just copy paste this.
Fresh. We'll say password.
Placeholder will just be.
Like what is this? Like 3Password bullet symbol.
It's like a Japanese flag.
Base holder can be like this.
And then here we actually, I actually pass type inside of this component. So we can kind of use the type correctly now.
Yeah.
It'S going to be required.
Definitely.
Password is required. Pattern. Let's do some cool password. Regex special character. Have a length of 8 in number.
Cool.
Minimum 8 characters, at least 1 letter and 1 number. Minimum 8 characters, at least one letter, one number and one special character. Minimum at least one uppercase. Let's do at least one uppercase letter, one lowercase letter, one number and one special seems to be a good answer.
Let's take this regex.
And add it to the pattern.
Go.
And then the message will be.
All right, now let's check if that works. Fresh Password is required.
Minimum eight letters and maximum of ten characters at least one uppercase.
So.
Oh, and I did add the type. Let's not add that yet.
One second.
So let's go like let fill 0011 exclamation point. Oh, it needs, it needs to only be 10.
All right, let.
No, that maximum 10 character is. I'm going to get rid of that one. I think that we just need to get rid of the 10 here.
Yeah, I leave the comma. Yes, I do need the comma because.
It'S saying, hey, it can be anything.
But at least it's all right. And I'll just get rid of that.
Religion.
Peace out.
Thank you, Phil and Minnie. No problem. Thank you for joining Mercy.
Thank you for being here.
So we're going to go back to our form validation and press submit. It's in our submit state. So now let's do let fill 0011 exclamation point. Minimum eight at least one.
That's.
Well, this regex is not working very well.
Go this one. It's because of the quotes. Not true. This.
Okay, yeah, it was because of the.
Quotes and then commit.
And now password is valid, but we do need to change it to like. So you don't, you don't see the like password. So that's why I added the type. And you could add a type into the control into the form input. So that one is.
We just have to add type of password.
And now you Won't be able to.
See the whole thing. So that's pretty cool. Yeah.
Well, and then confirm password.
Just going to take this guy.
Remove.
This input, add the confirm password and in the validate.
Hold on.
So confirm password is going to be required.
There's going to confirm password.
And placeholder control type will be password required. Maybe we should add a button inside of the password. We say show password.
That'd be kind of cool. We can do that in a second.
So it is required. Confirm password is required. And I think there's something, there's something called Validate. Let me figure out how to use it real quick. Or we can just look at the code that I wrote earlier. Validate. And then it runs a callback on value. So the value. Okay, it runs a callback and then.
It passes what we need to. So just get this one, just copy paste it. So how we're going to do this.
Is validate is going to run a callback on every key down on when the value changes and the value of that input. And then we're going to get the value, get the value of the password that is already in there and check if it's true or false. And if it is false, it'll pass a string and say passwords do not match. So let's go there. So password is required and we're there. And now password does not match. But it matches. But it doesn't. It won't pass. So now we have a pretty cool form here. And I think we can add a button to say like show password and show confirm password. Because sometimes it gets kind of confusing, like, oh, like these passwords don't like work.
So.
Let'S get that going.
Like, I don't know what I'm doing wrong, but if you have the show password there, it's better for the ux, I'm pretty sure.
So let's go.
We can do.
I'm thinking let's just use Date or.
Do you guys want to learn Use reducer?
Maybe it'll be better. Yeah, let's use reducer.
I'm going to pull form. Let's do User reducer. I think it's a good, I mean it's pretty much used with Use Date, but User Deucer will kind of will teach you how to use it. And let's move this into a different file because it'll make our code look a little bit cleaner and that's what we need to do anyways. So I'm going to run the form input and the I form Input into different file I'm going to make in the signup form in the src, I'm going to make a folder called components and inside of there I'll make form components and inside of there I'll make.
The form input and do like this.
And these are all missing imports. So how we can handle that is you can right click and just import all on. This may be a stupid question, but only if only numbers are required for the password and someone uses a number out of the 64 bit range. Is the data type relevant there? Is there any kind of basic error message? I think the password will only handle the like character at a time.
So.
Is that answering a question? Because I don't think it'll ever have to handle like a 64 bit number, but I think a 64 bit number will be handled by the length. And in the input of a password it's always a string anyways, right?
Okay, okay.
Oh no. No need to be sorry. So like the way I handle this is I just press like command period over my missing import and I'll just be able to add the import anyways. So like this build values.
And I'll just put an export default here and controller this and pretty sure we're done now.
Yeah, so that. That imported all the stuff that we needed. And I was fighting with my computer earlier, like earlier because the type for this is really hard. But I'm just going to show you guys in the complete one.
Let me.
Close some stuff out so it doesn't crap save. This is the form input that we just did. And then in the complete one there's components and then the form input here and the way it said to do it was control with the field values.
And we'll do that then. So field values.
But then whenever, whenever I was using it. Right.
Wait, is this in the. Hold on one second. Getting a little bit confused now save.
And then app TSX inside of less.
Than 6 sign up for.
So now inside of the form input.
Oh, okay.
And then I'll import the form input from there. And then I was getting this really weird control type error, right? And there was a workaround, I think not this one. I just hovered over. I said control username. Any types of types of reset are incompatible is not assignable to this. I just, I think I typed this into Google and there's some kind of GitHub form here. I just scroll down, scroll down and someone had a workaround.
So I just did.
As unknown and then as.
So show you. So this.
And that Seemed to be the workaround. But I mean, I don't know if it's like super good or not, but it works. It's good, I think gets rid of it. But what it's actually saying is, hey, I don't know what control is at this time, but this whole control thing, I will type it as control field field values, which was the field value at before. Right. And so I'm wondering what would happen if you just did like this.
Break it, I guess.
So first you tag it as unknown, and then when the unknown is happening, you're using as the type that we put a typed.
So just do like this. That we have four of these guys, right? Yeah. All right, cool. Right. So.
Now I think our form is pretty good. Hello, that's coming from our watched username. Hello@babybye.com.
Goodbye.Com. Let Bill, capital L. Let Bill.
Try.
To submit and then we'll get a pretty good submit.
Right.
And I did want to do the show password button. So let's try that out now. And we can get rid of all these imports because we're not using them anymore. And now our code is nice and short and complete. We're not even using this really. So let's get rid of this. I'll comment it out. I'll put it on the bottom in case you guys want to pull and take a look at how to use it. And it's kind of good for like, maybe you need to watch some numbers coming in and need to add like the commas or something like that and you need to like watch it every single time. So that is a use case for it. And I just want to clean up the code as much as I can. I'm sure we could. At least we could even put the label inside of our render so we don't need to. We actually wouldn't need to import all of it. Yeah, let's just add the label.
Let's do that.
We'll see. And then inside of the form, input form, components inside of the render. Why don't we just add.
Wait.
This.
This and this, and then that way.
And then we just pass in here the label as well.
Right? Label text and then we can pass label text and then that's going to be passed.
And then in here we can pass.
Label text as a string.
Now we can actually.
Get rid of all these label things, I think, and just add label text to confirm password and do the same thing here. Password something here. Oh.
Crap.
Why did that happen? Probably because I didn't save this. Okay.
I didn't save.
Sorry.
So label text string. And now we have everything componentized and I'm thinking we can even do one step further because we are using this compo same component four times.
Right.
So let's get to making it more.
Clean.
I think. So we are using the form. So I think we can do something.
Like const form values.
Let's call them input values, make an.
Array and hoping this will work. So.
We'Ll say something like. And the name and the label text. Text is always, almost always the same, right? Label text, name, name, name. It's just capitalized. Capitalize the first one and then if we find another capital.
No, that's too much.
All right, so the props that we send is wrap label text is a username.
Name username.
Then the only thing that's different here is our placeholder.
Username. Let's say the same thing.
And then the rules will be. The rules will be pretty.
Descriptive for that one and doesn't need a double double.
And then for this one it's the email. We'll just grab the roles.
We'll grab the roles.
There. The next one is going to be.
What like comma, label text, email, name, email, placeholder, email. And then the rules copy like this object and o.
Got to do two more.
Label text password. Oh my God. And name password, placeholder.
Lower down there.
At the same time. So required. We'll get the rules and grab that and then rules grab the rule on.
Here and the last object will be.
Label text, confirm password.
Name.
Confirm password, placeholder.
Placeholder.
And the rules will just yoink off of here. There we are.
And these guys have types so we.
Want to do that too. So and rules like so and we.
Right now we know that it's going to be a string so we're going.
To go like that and then so.
On the input values. So if I just wanted to make a type for this real quick.
I do label text as a string.
Name as a string.
It'll just help us in the wait.
String rules would be in any. It's an object that's not like same for everyone.
And then sometimes it has type where it's.
Hey Phil, gotta go run Samaritan. Thanks for the project showcase. No problem. This will all be uploaded into GitHub soon. It'll be uploaded and you guys can take a look there. And then the type will be either password or text. And there you go. And now.
I think we could just.
Screw writing all this code here. I don't even know if we saved.
Any lines there, to be honest.
Input values.
Dot map.
Is it called input value? Yes, I meant.
Oh, why don't I capitalize it? There you go. So input values. Oh, that's going to be an array. There you go. So input values, dot map and then it's going to take a callback that arrow away and then I'll do something like input value and I'll return. I don't think we're going to do much more than just return here. So we can just do like this and then form input.
And then label.
Text will equal input value dot label text. There's another one. Type equals input value dot type.
And can I get a link here? Yeah, no problem.
Right.
Oblivion. If your name is the same as in discord I'll message you same one on one. And then if not, I think it's gonna be. The link will be in the GitHub YouTube video and they're in the video for like the last one there. The link is in the video. The last ones too. Type.
What is.
What are the other ones in input.
Value we have input value type. Let me see here.
Placeholder.
Optional because not all of them have type undefined.
What is another one that form input needs form input also need rules.
And.
Then it also needs control. What is that control that we made earlier?
So it was.
It was control as unknown then now we know.
So control at field value stuff value. I think that's what it was.
And then the last one it needs is name.
So.
Now it's very similar to what we had before. I think the placeholder is a little bit off. Placeholder should actually be like emailadfill.com or something. And each child is in list should have a unique key. That is true. So we got to put a key I usually use like the index and then you can do something like this.
You need some backticks. Use some kind of thing like input.
Like a unique value from the array. And then I also put something like.
IDX to string and that should work really nice.
Now we're all good.
We're at the same place and the.
Placeholder should actually be different.
It should be let mid.
So guess that gmail.com.
Oh, this is that.
That didn't work very well.
Because I didn't pass it. All right.
Now we need that. The show password thing that I just kept on saying.
Right again too.
So let's. Let's do that. So we need two buttons on the side of password and confirm password I guess. Right. So thinking here. So inside of here Maybe we can put in the render if password.
If.
If name equals password or confirm password. Put a, put a button here. So like I think maybe here.
You can put a span and then we can say something like.
Name equals password.
Or name equals confirm password. And you can add a button. Show a button here, not here. Oh, let me think here. I want the expression to be like this.
These grouped together.
Yeah. So I actually like the show button over here. So what if I put it with this expression here? Good enough.
All right. And then.
Just got one click.
That's going to be a show function.
Show.
Call it show func or something.
Show. Call it show password. Just call it show.
It's going to be a void function.
Just call it show and whenever.
And show is actually a optional. And show will be used on the.
On click of show. So, so view and this just get rid of some deadlines. Right.
And do you want to use a reducer?
We can say constant. How do you do this? I think state. Let's read about it real quick.
Use reducer. And it takes some kind of actions and it takes an initial, initial state. And then from there it gives back two things and then one is the state and one is the dispatch. Dispatch is how you call the functions. I think this is how you. And then this would be like the initial state.
So test. I just want to see if that's true.
And I think it's a callback actually.
So use reducer.
Void. It's getting the test string. And then the initializer.
And then reducer is a void function. That's correct. So take something called payload.
Think what happens takes an action and a payload, I think. All right.
Switch.
On payload action.
And then on case of show password. Ah, okay, sorry. Then we need to pass state plus change. Really forget.
Hold on, let me just look at, look up the documentation real quick.
User do, sir.
User state, dispatch. The reducer takes state in action.
All right, all right, all right. So the register takes in the callback.
It's state and an action. And then the state is always there. So the action has something called a payload. Right? Oh, and something. Oh, type. So action has some. Okay, Action has a type of what kind of action it would be.
I'm just gonna print any command. All right?
And then it'll be the state.
And then it can change.
Show the password. And.
Action take will incriminate. Age equals state one. Right. So let's go here. State. Let's just see if it works.
I want to constant log state.
It should say state equals state.
I Get that? And then if I were to dispatch.
On show password like this, and then.
If I pass from there, I'd send some action password.
I do action payload, right?
And I do send some kind of.
Test payload. Whoa.
Okay, we're not allowed to do that in here.
All right, So I would have to put a button.
So instead of putting the handle submit on that button that's just tested for.
Change on, click special password and test payload.
Expected one argument, but got two.
All right. Special password and test payload.
I expected one argument, but got two.
All right, all right.
So dispatch, press that state equals undefined.
Okay. And then how do I pass the payload?
Let's go until max 1145. Okay. I'm just getting this reducer ready. 1145, is it. People are dropping out really, really fast, right?
Yeah, yeah, go ahead.
Keep on.
It's okay. Just for the content anyways.
It's just.
Wait. Action. Action.
You should be able to pass a.
Payload with the dispatch, I thought. Let's see here. Action, Action. Next. Name. Action, type. Oh, crap. Okay, one object.
So you pass the type.
You pass type and you say like show password. And you see payload.
We'd only need to pass the type actually.
Right? So then let's just go over here. Action. That payload is not sent, actually.
So he's going into this case now, right?
That's pretty. Okay, I got it. And then console log. Action equals action.
If I do this action has show password. So then that show password will. And then our test initial state should have a show password.
And that should be false. Show confirm password. That should be false. Right?
And when you hit the case of show password. And then you should do. You should spread the state and then you should say show password is the opposite of the state. Show password. And then you should do something. I should do something similar for show confirm password.
Return state, and then do something similar. Show confirm password.
That's the opposite to state.
Show confirm password. Wondering if you have to put the state here. Yeah, all right, all right, all right. Show password. Show confirm password. Boolean. Yeah, there you go. And the action will be.
Hype. And it could either be show password.
Or show confirm password. Right. Okay, further.
And now.
Okay, anyways, so now refresh and we.
Got to hook those buttons up to here, right? And actually this still has to be that on submit.
So.
On form submit.
Now let's say.
We can say something like. So here we'll put a. If the index. If the input value dot name equals password.
Thank.
Show as the dispatch to.
Type show password.
String Type password text.
Right? Oh, too many renders. Oh, that's.
That should pass our function now. And now we get it switches back.
From false to true, false to true.
So we also need. Let's just do that here. We can do it all in one.
Line, but I'll do it here as well. Oh, confirm password. That's going to be show confirm password. That should change.
Change. It's a double log because of the strict mode. But anyways.
So now all we need to do is on the type. The type. Okay, so let's do some thinking.
If state dot.
Oh, we can go on the bottom actually. Right, Got rid of that.
This state.
It's this. Right?
So we only need to pass a type if it's true, right?
So we can do something like this. We can spread on if the type.
If input type, input value, dot type is there. So if that is true, true, truthy value.
And now if.
So now at this point we know that it's only password and confirm password, right?
So I'm just thinking here, why don't.
We do one more case and which true and if.
Input.
And then the state dot.
Now the type will be undefined.
And then here at this point, the type if.
And we'll put two checks.
If input value dot name equals password and input value name, password and state dot show password. So that's true.
Then we want to password, right. And if not, then we can just pass the text. Right. All right, now we kind of have.
To do it for the. For the other guy too. I think we can just do these all in one line. But.
Refresh. Whoops. Mess something up here.
We do have to put it on one line.
I didn't start. I don't know, man. Oh, change it back.
We didn't do it with reducer. It would have been so much easier, I think.
But yeah, let me figure it out first. Guys, working.
So this guy's saying, hey, if is if in if input value dot name equals password. Do this stuff. So now actually we can just do like this. So and if state show password. So state show password starts out at false, right?
So I refresh. This should be like. Instead of passing this, it should be undefined, right? No, why is it, why is it passing the type as this false right now, right?
Oh, did I do it backwards?
Oh, oh, sorry. Okay, that's good. And then we can just add this one for this one too. All right, cool, cool.
So now we can totally make a cool like validated object now. So we can say like user name1.
Usermail.Com password00z password00z submit passwords do not match.
Let's show these guys. Oh crap.
I need a cap.
Like this. And now I can submit. And then it'll submit a cool little form validation thing that we made today. And I will push this code. I hope you guys learned something. I thought it was. We got into some debugging and logical thinking. I'm sure I could clean this code up a little bit more. But it's thought it was pretty interesting. Like this one, I feel like maybe we could have put an or like we put or input value.name equals confirm password. Right? And then we could actually gotten rid of that one and then we could have just concatenated like this.
I'll show you guys.
Or we could have just put the check here. So we could have said input val input value name equals password. Then the dispatch will be show password. If not, it's going to be the.
Show.
Share confirm password.
Then we're to shorten this code down a little bit. So and this one we could have shortened. I could have shortened as well the same way. It will do that now.
So and this one, if input value name equals password and here would be just password or wait, whatever it would be show password.
And then otherwise it would be the.
Show confirm password and we could have.
Gotten rid of this one then fio.
Then.
Maybe it could have been cleaned up a bit more. But if we keep on getting into that, I think we go on forever. But this is working perfectly fine. And I'll push this code. Thank you for staying. Jocelyn, Alex and Peter, you're real ones. And we will chill for like 15 minutes. But I hope you guys learned something. It's been fun. We made the form today. We made the form input like a pretty cool mod component for handling form validation. You guys can play around with the css. We handled making a form and dynamically doing it. Like it would be super easy to add another form value right now right on the bottom. Like we just did like that we would add another value and you could actually go one more step and make a function to spit out this object. I think that's pretty cool. And yeah, we got, we got through it and it was fun. And I'll probably use this code too. It's this dispatch thing.
It's pretty cool.
I think today's is over though. Thank you guys.
Thank you for being here.
What did you. What did you think, Minnie?
I thought it was super valuable. I think, you know, it's like something that every junior developer needs to know for sure.
100 going reactive form I think is really powerful.
It's so much better than doing just forms regularly.
I know.
Right?
I did.
Because Forms.
Dude.
And there are other ways like with Zod and. Yup. But I mean this. And I think we even got a lot more into not just form validation but we got into kind of like REACT too. You know what I mean?
Absolutely. Yeah.
Like making these objects and kind of making typescript work for you.
Definitely. Yeah.
I would have gotten really confused if the typescript was not there.
But typescript was hard. Dude.
Typescript. I like Typescript. Like at a. To a certain degree.
Right. Like.
And with REACT is very good.
Right.
Because you're always playing around with props and you don't know what data types there are. But Peter, thanks for staying man. Are you there?
The last one. Last man standing, brother.
Yeah.
Nice. Appreciate you man. I hope it was. It was good. I know. You know we. You have to learn every little piece. You know and then you get. You know. I think we have a lot of a project now.
To be honest. Yeah, we do.
So what's next? Are you going to combine these together now?
Exactly. Exactly.
And we could make. And honestly I might just copy this sign up form over to lesson seven because I set up everything here now.
Because right.
Right now like inside of Main tsx we have access to like the storage inside of Firebase, the DB Firestore authentication. And then I actually wanted to get into Molecular.
That'd be pretty cool man.
Molecular with Mongo.
Some people probably hasn't even heard. Haven't even heard of that one. So.
Of course.
Or Nest js.
But yeah.
Peter, where are you from man? Look a lot less tedious to implement the authentication form I tried while learning MVC framework. I know right? It's Getting that payload started in the View is definitely something that we need to do. But now everything is ready to get put into the database.
Very cool. From uk.
That's awesome. Where in uk? Manchester. Are you going to see OASIS.
Reporting right here.
More from Phil

day in the life of a software engineer | 5 hour productivity | building my dev agency 🔥

day in the life of a software engineer | 3 hour productivity | coding my 6-figure community startup

day in the life of a software engineer | 5 hour productivity | coding our sns startup app LFG

day in the life of a software engineer | 5 hour productivity | creating apps that makes big money






