How to build elegant React forms with React Hook Form

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
react is amazing for many things but one thing it's bad at out of the box is formed so when we go to build a form and react we spend most of the time working around its limitations and doing things like preventing default Behavior instead of embracing it so today we're going to take a look at how you might typically construct a form and react and then we're going to convert it to using react hook form Library instead and try and explain to you why using something like reactive form library or another similar form library in react is a much better idea than just doing it yourself okay so for the purposes of this demonstration I've set up a react app using feet and I'll link a couple of videos below about feet if you want to learn more about that but this is a very simple app I've set up two components here one is the main app file and the second one here you can see is user form so I import user form into app I have an example user already set up with some information um and I am then I have a handle Save which basically console logs out the values I'm going to send back and then here I'm just rendering the form passing down on Save and passing down the user value so if we have a look inside the user form we'll just have a quick look and see what that looks like in the app so here you can see we have react forms we have the name email website and Country values with a couple of drop downs um so if we look at the code we have here we have the user form we have use the data so we're taking the initial user which might come from the API and we're setting that in state so that becomes user data we have some errors here that we're also using setting and state and that's it that's initialized with an empty object um so we're taking the user data which if it doesn't exist is an empty object as a default and we're going to destructure name email and website from that and we can also do country and save ourselves some boilerplate down here so we then have a validate data function so we have the errors object and then we're going to validate if the name doesn't exist we're going to validate using the validator library email and if email is not an email we're going to say valid email is required and again the website if it's not a valid URL we're going to validate that as well we then have a handle change function which takes an event inside that event we have event.target and we take the name and the value off of that we then set the user data using this previous data that using this callback that set State takes we're going to spread the previous data and just replace the name and value that we've changed so we also have handle select change which is a different change Handler for the select itself we then have a handle save function so that'll save function validates all the data so that's where that validation gets called so then here we check if there are any errors and if there are we set them in state and then we return so we're not going to continue saving the form if there are validation errors if we've gotten this far we can reset the errors to an empty object and we will call onsave user data which then passes that back up into this handle save so then we get down to the form and we've got um this is just a very rudimentary form put together real quick but we have like a label name we have an input with name of name value of name unchain title change so each of these has a name a value and the same on change then we looked at the select component and you can see that has a value which we got to take off the country options object you can see that has its own unchanged and this is where we pass in the object of country options and these are up here defined up there um so I'll show you real quick how that works so we take a look at I want to change the name here to Thor and we'll say Thor at marvel.com changes website to thor.com change the country to Asgard and if I click save we're getting this console.log value out we've logged it in two places so we've logged it into user form and then up in the app we're also logging the values so at this point we will then take these values that we have saved from the form and we would send it to the API so that's totally fine right but if your form starts to become more complicated a simple form like this is totally fine but if your form starts become a lot more complicated has different conditionals has different validation requirements and this whole thing becomes a lot more complex so to solve that we're going to convert this form to using react hook form so this is the library that we actually use at work and it has saved us so much boilerplate and so many headaches with these validation Hoops that you're jumping through and I think it's a really well thought out Library so we're going to go to the documentation here and I will click on get started and basically we just want to copy this install react hook form so command J to open up the terminal here and I'm going to stop the server paste that in npm run Dev start the server again command J to close that and what I'm going to do instead and what I want to do here is import use form from react look form and we will start by showing you what is in the use form hook so I'm going to say const used I can't call that use form we'll call that all right I'll call it rhf for reactive form equals use form call that and I'm just going to console log this out real quick so you can have a look so we'll go back here and inside of here we have the react hook form methods so we'll open up this object and you've got a whole bunch of methods that come with the react hook form used form hook uh so inside here there's going to be a lot of stuff that we don't need for this demonstration um but some stuff that we will use so inside here you've got something like you've got clear errors which you can imagine is going to clear the errors you've got control which allows you to control the actions of a change Handler a little bit more tightly so I'll show you that with the select component that we have we have form state which holds things like errors and it tells you if the form is dirty or not so that's something that you don't need to calculate yourself and figure out if the form has changed you have some booleans here like it's submitted and it's submitting is valid it's validating all that stuff is super useful um get feel State get values this is how we get the form values I register is something we're definitely going to use in this in this demonstration um we can set focus of an input so we don't need to mess around with refs to actually focus and input on component mount for example um trigger is a function that triggers validation manually which you don't need to do in this example but there might be cases where you might want to trigger some validation based on something else happening um so let's take a look and see how this will actually work for our form so instead of returning everything I'm going to destructure the things that I need so I'm going to start by destructuring register and control delete this and I'm going to delete this other console log down here now the next thing we need to do is actually wrap our form in the HTML form element so you can do that in react anyway and I'll show you real quick so let's say instead of div here we could have done form and down here is form and instead of having an on click on this save button we can delete that what we can do is unsubmit equals handle save so this would have worked except you'll see there is an issue in react in terms of how this actually works so I don't have a non-click here the button would be a type of submit for this to work and now if I click handle save okay so I've pulled this down just so you can see what happens but keep an eye on the browser up here so if I change name to Ian and then I click save watch the browser bar up here see it's actually refreshed the page and it's passed as params the entire value of the form so this is how HTML forms are designed to work but it's not really how we use them in react so often to get around this instead of passing you can see the website is here the email is there in the name to get around this we always take the event and then we say event dot prevent default and we call that so here instead we'll go back to this clear this change this to and again click save page doesn't reload because we've prevented the default behavior of the form and again we got our values logged out because the page hasn't reloaded we've just sent it up to the to the function in the parent component so I'll go back into the export form documentation and I'll have a look down here and you can see here we have the form components so I'll go back to the code and I have form and I have on submit equals handle save now we're going to need to use register to set up this form so that it can use react hook form and I'm going to console logout register again so you can see exactly what register is so we'll reload the page here and you can see so you can see register is actually a function that takes a name and some optional options so if I clear this and I'm going to start by saying register and I'll pass in name because that's actually the name of the first input that we're going to be looking at and so I'll invoke that by passing a name and then see what we get here is we get name back we also get these functions so on blur on change and ref so immediately you can see here now well what are we going to do so instead of passing in an unchange to all of these inputs I'm going to delete these I'm also going to delete value and I'll leave name there for a second and what I'm going to do is spread the result of register name I can delete that because as you saw here it already it's already passing a name by us spreading the result of this function being invoked we're giving these keys or given these props to the input so we're giving name we're giving on blur and we're giving on change and ref so we don't need those so I'm going to do the same here to email and to website okay so we now have this form with an on submit that takes handle save but we need some way to communicate with react hook form when we press save right so use form returns a function called handle submit what we want to give to handle submit is a function so we're gonna instead of handle save here we're gonna call handle submit handle submit will do its react hook form thing and then it will pass the result of that which are the form values to handle save so we should still instead of event here and instead of user data which is in state we should get form values which we can then pass through to our fake API function and I'm going to comment out this validation stuff for now so if I save that refresh you can see we still don't have any initial data because we haven't set that up yet but if I put my name in here I click save suddenly we have the form values that we've set up with react talk form so I can put in at marvel.com a website clear that click save and then we've got these three values Ian marvel.com name and website so let's see what happens if we register country in here and we can get rid of value and on change right so if we select that we call and select a country Scotland we've got an issue can't read properties of undefined reading name so if you remember a handle select change up here takes the option a handle change takes an event so register is expecting this sort of format where it'll handle a normal unchange but if you're using a component like this react select select component you're going to need a different way to handle on change so we use something called controller from reactive form which allows us to you know have more control over the change event itself so up here we're going to import use controller and we have control already here so what we can then do is return an object which contains something called field from use controller and that takes an object itself with a name value and so we're going to try and control the country field and then it also takes control so control comes at a used form here and this is how we link this controller with this use form instance so we can then go down to the select here and we can say value equals field.value delete this on change is handle select change and inside of handle select change I can say field.on change pass in option.value get rid of this so I know I'm getting options straight out of react select and then I just need to pass in the value into the on change and let's see if that worked so I'll change the country to Scotland here and if I save it you can see that it's in the values but it's not displaying properly here in the react select so if I go back to what I had there country options dot find field.value and there we go Scotland so we can now change it to USA press save our form values now have Country USA so if I call Ian in marvel.com change that to Asgard call Save and then we have the entire form values coming out of react hope form so one thing we're missing here is validation so all of this boilerplate for validation can go this handle change can go because we don't need that anymore and let's have a look at what sort of validation we were using here we also don't need any of this because that's all stored in the use form form state errors can go this state can go um so what we need to do is first of all we need to pass in the initial values into the form so I forgot about that so use Forum types and object with default values default values you can take user as long as the keys are all the same name email website country you should see now errors is not defined so I'm going to comment all this out and let's just say for let's get this working for now errors equals empty object so yeah so you can now see the default values have gone straight into the form so I've changed that to Thor press save it's returned all the values including the one that I've just changed close that so to finish off we're going to take a look at validation so I'm going to use a library called Zod for validation react hook form does have its own validation I find that using something like yup or Zod is way more powerful and so for the purposes of this demo we're going to use assads so if you go down here to scheme of validation in the documentation you can see here it says we also support schema based form validation with the upazod superstruct and joy where you can pass your schema to use form as an optional config so this example is using yup we're not going to use you up in this example because it's not actually actively maintained as far as I can tell so I'm going to use Zod instead which I'll open here in a new window Zod is a really great powerful library that is as you can see actively maintained so we'll sort of adapt the documentation here to to work with sod so I need to install hook form resolvers I'm going to copy this and go to the terminal close that paste that in and type in sod instead so while that's running and we'll start the server again and I should be able to import solid resolver from resolvers slash sod so we're going to import Zed from zot and then we're going to create our schema so say schema equals and then we can say Z dot object we're creating a schema which is an object if you have a look at the documentation here you can see an example of creating an object schema so we've got some strings so we're going to say name string and we're going to say email and that would be string dot email so that takes care of our email validation we're going to say what what else do we have uh website so I'm going to say website string dot URL and then we'll just say country which is also a string and uh Zod does these validations as as required by default if you wanted to say you know let's say website is optional you can just add an optional function to the end of it just there so this game looks like this and then what we do inside of use form is we need to give it a resolver and we will wrap our schema in the Zod resolver schema and just before we finish that up we will get form state out of use form and we can get rid of this and we can destructure errors off of form state that's not a function and down here we are displaying errors in a div instead of name errors is an object with a message each one is a message so if an error for a name exists we need to name if name exists so name Dot message all right stop doing that please message we can say errors dot email dot oh my goodness oh let's get rid of this and type message I have my optional training in afterwards we can also do the same for country Let's test that out so we'll refresh the form here and we can delete a required form value click on Save and the first thing is enveloped it's invalidated the URL which says interesting because that looks like a valid URL I think it might be yeah it's it requires a HTTP so um URL on its own may not be good enough or you might want to encourage you might want to append the HTTP values you know in front of the actual website itself before submitting the form so that's something to be aware of the other thing is it's taking name as an empty string as a valid string so so what we can do to combat that is say instead of allowing an empty string we can chain Min we'll just pass one in there and let's try that again so we'll delete this and we will make sure this is valid and get rid of that and you can see the validation is string must contain at least one character so you can see that Zod and reactive form have come up with a a actual error message so you can customize that if you want so inside of here you can give it a second a second argument and you can give it a message and we can just say name is required so we'll go there again walk around this for now delete that and we get name is required as a validation so that is in a nutshell how react hook form works that's how you would use a validation Library like Zod um I've just kind of scratched the surface here on how you could use these libraries so I hope you can see the value in using them for your forms inside of your react apps instead of using the clunky default sort of react implementation for forms but that's it for now thank you for watching if you like the video make sure to hit the like button and subscribe to my channel and I will see you in the next video
Info
Channel: Ian Lenehan
Views: 46,877
Rating: undefined out of 5
Keywords: react forms, react hook form, react js, react hooks, web development, react form, learn reactjs, react form validation, react forms tutorial
Id: 4oCH5WaJHzk
Channel Id: undefined
Length: 22min 34sec (1354 seconds)
Published: Wed Oct 26 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.