React Formik Tutorial with Yup (React Form Validation)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on guys welcome back to another video so today we're going to be building some react forms using the formic library and we're going to be using formic to handle the form state and the validation and error handling and all of that so we'll be building a basic form here and we'll also build another form that uses different kinds of inputs like the select or this checkbox so it should be pretty straightforward and just some basic knowledge of react is required so let's get into it [Music] all right so i have the starter files open here and these are going to be in the description below as always so you guys can follow along so right now we just have these two forms and they have a single label and an input if i open up the app we have our view and state here and in our nav links we just basically set the view to either basic or advanced and then down here based on that view we either display the basic form or the advanced so if i open up the basic form this is just a bare bone html form and typically with react forms when you're not using formic you would have some sort of state above and in our case since we have an email input the state would be email and down here the value of this input would be equal to the email state and then the on change handler would call the set email set the email state and that would get reflected in the input but with formic we don't have to worry about any of this state management they handle all of that for us and i didn't mention this in the intro but there's two different ways to use formic and one of them is to use the use formic hook so let's import that in so we could do cons formic equals use formic and if we look at their docs they use formic hook is just a custom react hook that returns all formic state and helpers and the helpers are basically just functions that help us to manage the form state and if we scroll down to the example they call use formic and then pass in an object to configure it and one of those properties is initial values and this is what is going to handle our state and then the onsubmit handler and a bunch of other fields so let's go back to the form and pass in that object so we want to give it the initial values this is going to be our state so right now we just have an email input so we'll put email and then the default value will be an empty string now the use formic hook returns the form values the state values and a bunch of other helper methods so to use the state values we can come down here and we'll just do value is equal to formic dot values and this this property is going to be equal to these values here that we defined up here in our state and we want the email property so we'll do dot email and then on the on change instead of defining our own function we're going to call the formic dot handle change and this function comes from formic and it's going to know that to take in the onchange event and set the formic state based on whatever value it it's looking for so in our case it's the email so if we just hit save here and i'm also going to log this formic to the console so you guys could see the form state and the different helpers so we'll hit save and go back to our app and open up the console here okay so here's our object with the form the formic object so if we see here there's a ton of different methods and if we scroll down to the bottom we could see values here and it has our email so that's when we tapped into formic which is this object dot values dot email so if we type here asd we come down go to the values we'll see that here and there's all these different methods and we're going to go over some of them like touched and set submitting and all those other ones so we come back to our app we want to add some more inputs so let's just copy and paste these and we'll add the other properties that we need so i went ahead and copy and pasted the rest of the values and they're basically identical to this email so for age we have a type number and it's tracked by the values.age i also added this on blur and this basically validates the form when you click off of the input so i'll add that to our email and then for our password it's going to be of type password with the password value in the state and then same thing for the confirm password so let's also add a submit button down here and that'll just submit the form and then i'm going to add those pieces of state up here so age is going to be empty and then password okay so now we have all the values that we need for our form and then all the inputs are tracking those different values so if we open up the form again just refresh you come down here and just enter a couple values for these we could see all the way down here they're all being tracked in this values field so let's go back to our app and it's kind of annoying to constantly put formic dot and then whatever method or or property that we need so instead of just capturing it here like this we're going to destructure and we'll just destructure all the properties and methods we need and i think that's all so then we'll just come down here and remove all the times that we put formic and if we hit save this should all still work and it does okay so if we if we hit the submit button now um we do have some validation there just from the input field but right now it just submits our form and it doesn't validate that we even set a password or our age or that it was a number or any of that so let's add some form validation for that we're going to be using the yup library and that works really well with formic it's actually built in to formic to use that library so in order to use it we first need to create a schema for our form and our schema is basically gonna define these different properties and it's gonna basically say what those properties should be or what types they should be so let's go into our source folder and create a folder call called schemas and in here we'll just have our index file so to create a schema we first need to import yup we'll just import everything as yup we need to give the schema a name so we'll do const basic schema because this will be for our basic form and that's going to be equal to yup dot object and then we're gonna chain a method and then we're gonna call the shape method so this schema is gonna be equal to an object that we define with this shape and so in here we can put the different values that we want to validate for so in our case we want the email and then for the value here we can call you up and then a bunch of different methods that will describe the type and some other validation that we want so we can say that we want it to be a string and we also want it to be an email so yup will validate that it's an actual email and then we can also pass in an error message if this validation fails so we can just put something like please enter a valid email and then lastly we want it to be required so we'll call the dot required method for our age we want it to be a number so we'll do yup dot number and it needs to be positive also needs to be an integer so we'll add that and we also want to make it required and we'll also give the required field a custom message and we'll just make it something simple and concise now for the password we want to make it a little more complicated so we'll do yup dot string and we want it to be a minimum of five characters so we'll call the min method and pass in five and then we also want it to match a certain regular expression so for that we need to call the matches method and the first parameter here is your regular expression so i'm just going to paste that in and so these are password rules if you don't know anything about regular expressions they're basically just a way to validate some sort of inputs based on these rules that we found or that we defined here and this regular expression is just going to ensure that we have a minimum of five characters one uppercase letter lowercase letter and one number so we can just pass this password rules expression there and the second parameter for that is going to be a message if it fails so i'm just going to copy and paste that message and lastly we want to make this required as well with the same error message okay so that's it for our password and then for our confirm password we want it to also be a string and we're going to call the one of method and the first parameter that we pass in is an array and that's going to be an array of different values so in our case we want to make sure that this confirmed password is of the same value as this here and for that we can call yup.ref and that stands for reference and then we'll pass in the value or the property that we want to reference so we want the password up here so we'll call ref of the password and then we'll give it a null default value if it doesn't find it or it's not defined or whatever so and then we'll also pass in an error message if this field fails so passwords must match and lastly it's going to be required okay so now that our schema is defined let's use that in our form so we first have to export this so we'll do export const basic schema and now in our form we could come down here in the use formic configuration we could define the validation schema down here and this will be equal to the schema that we defined here so i'll just copy basic schema and import it at the top so now our form is going to know to use this schema and when we try to submit it it'll validate the form and basically display any error message or if any of the fields didn't pass now we need to define a submit handler so in our form we could call on submit here and this will be equal to the formic handle submit method so let's just grab that here and we'll just pass this into our on submit handler and so when the form is submitted it's going to call the formic handle submit and this function is going to call what we define here as the onsubmit handler so let's just define that up here okay so when the form is submitted it'll run handle submit which we'll then call this on submit function that we defined up here and to see if there are any validation errors we need to grab the errors property from use formic and then we'll just log that to the console so you guys can see what that looks like so we hit save and go back to our app let's just refresh and you can see first our errors object is empty but if i add say a password you could see here our form validates and the age its error is that it's required the confirmed password also has an error and the message is required and same with the email and then for our password you could see that it must be at least you know the the character five characters long whatever we defined in our schema so you could see that in that errors property we have an object that has all of our state properties our form state and it has an error message for each property but say if we have a valid property like age is a number and that's valid we go down you could see that the age is no longer defined here so back in our form right now it's not displaying any sort of error state so we want to show that the form is an error so in our form we want to go down to the input and we want to add a class name and instead of hard coding it here we want to dynamically add the class so first we need to check that errors object and see if the email exists so errors.email exists that means that there's an error in that field and if it does we're going to give it an input error class and otherwise if it doesn't exist we'll just leave it empty so we haven't defined the class yet so let's do that i'm just going to copy and paste some styles now if we hit save and we go back to our app we could see that it's in the error state and now if we enter an email it should go away but then when it's not valid it'll have this error message here that's defined and it will then add this class another thing i want to add is right now if we refresh and right when we typed it instantly went into the error field but we want to wait for the user to actually finish whatever they input and then when they click out of the form that's when it actually validates so for that we can add well first we need to grab the touched property and that's basically going to track whether the field has been been touched or used so down here we can also check touched dot email and we're just gonna add the and operator so first it's gonna check if there's an error initially when they've hit the first letter it will be an error because that's not a valid email with just one letter and then it's going to check if it was touched and initially this will be undefined because it first waits for them to input the whole field and click out of it and if that's true if they've clicked out of it and there's an error then display the error class so if we hit save and i refresh this and i type here this isn't about email but it's not in the error state but right when i click off of it it'll go into the error so we can just copy and paste this class name for all of the different inputs so if we hit save and we go back to our form this should now all validate the different fields and all them are working so we also want to display the actual error message like the ones that we defined in our schema so let's go back to our form and below the input we want to check for these same things so we're going to check that there's there's an email property on the errors and that it was touched and if that's true then we're just going to output a paragraph tag and this will just display the error so we'll do errors dot email and then we also want to give this a class name of error and that'll just style it so if we hit save we come back we should see that message there so i'm just going to add that to the rest of the inputs and now if we save and go back to the forum we should see all those different error messages that we defined in the schema so the last thing i want to add is a submit handler right now if we just enter this form and it's all valid and when we click submit currently it just logs something to the console and the these fields still stay filled out so we want to on the submit we want to clear all the fields and to do that we need to go back to our form and on this on submit handler we actually get some parameters so we get the values and actions and i'm just going to log those to the console and show you what they look like so i'll hit save there and then resubmit the form i'll clear this so first our values and this is an object here and it has our form state like our age confirmed password and all those values and the second one is the actions and these are all the different formic helpers or different methods that help us interact with the form and the one that we're interested in is reset form here and that's going to reset all the inputs but we want to mimic a api request so i'm just going to paste in this code and this is just going to create a new promise that we'll wait for one second and then resolve to pretty much nothing and then after that we're going to call actions and we wanted the reset form method so we'll just call that and this needs to be async and now we go back to the form and actually one more thing i want to add is when our form is being submitted we want to somehow display that to the user so it doesn't look like the the page just froze so for that in the use form of cook we can also get the is submitting property and when the user clicks submit that's going to be true so down here we want to say that the button will be disabled when is submitting is true we also want to give it a class name or actually when it's in in the submitting state we want to target that in the css and i'm just going to copy and paste some basic styles and we're going to check for any button when it's in the disabled state we're going to just lower the opacity so it's going to be a kind of blurred out effect so if we go back to our form and i'm going to re-input this so now i just click submit we should see it blurred out and then the form is cleared so this form is pretty much done and those are kind of the most common methods that you're going to be typically using and this is the way that you do it with the use formic hook so in the next form i'm going to show you how to do it using formic components and it's a little bit different but follows a very similar pattern now the first thing i want to do is to look at the formic docs so if we open those up and find the form a component scroll down to the example and you can see that we just use the component and we pass it different props and these props are identical to what we pass to the use formic hook so initial values on submit the validation schema all those things are now going to be passed through props and now to render the children it's going to use a render props pattern and that is basically just going to be a function that returns some jsx so in this props parameter we're going to have access to all the things that they use for mccook returned so all of these things the values errors touched they're all going to be accessible through the props here so if you could see in the output we have our form and the input the inputs value is equal to props.values.name and that's what's defined in the form state so this works in a very similar way to the formic hook and we can just copy this and paste it into our app and we need to import formic at the top and i'm also going to get rid of this on submit and also this little error and now if we go to our app we could see we have that input now so instead of rendering a normal html form we can actually just render a formic form and we'll import that and what this does is instead of passing the on submit handler here and make it equal to the props dot handle submit we could just make it a form component and not pass anything and it's going to know to run the formic handle submit method which we'll then call the on submit that we defined here so it just saves us a little bit of code and now instead of doing an input like this we can use a field component and if we look at the docs for that we could go here and we could see that the field component hooks up the inputs to the formic parent and it uses the name attribute to match with the formic state so we have to make sure whatever we defined in the state we'll have to use those exact same properties in the name and it also by default is an input element and if we want to change that to like a select for example we could just do pass in the as prop and do it as select so if we scroll down to the example we can see that we have our format component and then in our render prop method we're returning a formic form and then we just use the field like this so let's go back here and just paste that in and now the type will be text and the name remember we have to make it match up with our form state so instead of email we want this to be name and this will also be named and now instead of passing in the onchange and make it equal to props.handle change and the value and onboard all these things we now don't have to pass it anymore because formic knows since it's a formic field it just automatically uses the formic handle change and and the other helper methods so if we just save that and go back it should all still work and the on submit will trigger that submit form but we didn't have this defined yet so now if we wanted to configure this like say add a class name or other attributes we couldn't do it like this instead we have to go back to the docs and we can render a field component with children so instead of having having it be auto closed like this we could just put the render prop method in for its children and return some jsx again so in this function we're going to have access to different properties like the field which will be related to the input field that it is so so we'll have the name that we passed in or uh the value and then also the form which has the errors of the form or the values of the form and then also some meta info and then in here is where we would return the actual input so in here we could define the class name or any other info this gets a little bit clunky so instead of doing this i'm just going to create my own custom input field and i'll show you how to make that custom component have access to the form and the form state and all those formic helpers so let's go back to the code and create that custom field so let's go under components and create a file called custom input and we're just going to return a label and an input field all right and we'll remove these attributes because we're going to pass those in as props and i'm going to split this pane so it'll be easier for you guys to see we'll go back to our form and import this custom input so we want to pass some props to it and the first thing we want to pass is the label so let's add that and in our case we're not going to have a name it'll be a username and then we're going to destructure that here and that's what's going to be used for our label here and the next thing next props that we want to pass in are going to be the props for this input so we can do we could give it a name and remember this has to match up with whatever's in our formic state and we're actually not going to have a name we're going to have a username so this name attribute has to be username and then we'll pass a type to it and it'll be text and we'll also give it a placeholder enter your username okay so we're destructing the label here but we want to get the rest of the props and the way we could do that is to use this spread and this props variable is now going to be an object with all of these properties so we just want to go to our input and spread in those props so now our input gets all of these things and our label will get displayed above there so right now with this in place our label is just plain html and it doesn't know anything about this formic form or the formic state here and it's not going to have access to any of those formic helpers so in order to let it have access to that we need to use a hook let's go to the formic docs and that hook is called the use field and what this hook does is it helps you hook up your inputs to formic and so if we look at the example you have your form here and your custom component here you pass these props in and then in that custom text field they destructure the label like we did and just spread in the different properties but then they use this hook passing in the props and they get return of field meta and helpers variables and this field is just some info about the input field the meta has things like uh whether it's been touched or if there's an error and then the helpers are just those functions so let's just come and paste that in to our input and i'm just gonna log the field in the meta so you guys can see what that looks like and you don't need to see the helpers because we've already seen those and we need to import that at the top so if we save this and go back to our form we should see those things in the console so the field here has our name that we passed in username and the value is undefined and if we keep on typing you're going to see that this doesn't actually re-render and this field will still be undefined the reason for that is the field that the use formacook returned added on these functions so if we look back in our code we didn't define an onchange here on our input here so whenever the input changes it's not firing anything in order to use the formic on change that'll hook it up to the formic state we need to spread these functions into our input so then the input gets hooked up to formic let's go and we have our field here and remember it's it's this object and we just want to spread that into our input so we could just spread it like that and now this input is going to have the name the value and these functions and the next thing we have here is the meta and this has some other helpful properties like the error state for the input and whether it's been touched or not so we can use these to display either the error message or add that error class so now that we're passing those in if we hit save and you come back here and you type you should see that the value is now being updated here and the error is undefined and if we leave it blank there should still be no error because we don't actually have any form validation so let's go back to our formic form here and we need to add a schema so let's go back here and create that schema so i'm just going to paste this in so you don't have to watch me type and then i'll go over it so here in our schema we have a username a job type and an accepted tos field and the username is going to be a string a minimum of three characters and has to be required the next field is going to be the job type it's going to be a string and we're going to call the one of method which basically only allows these values to be in that field so we're going to have to define these later and it's also going to be required and then the accepted tos has to be a boolean and the only possible value is true for it let's save that and come back to our form and let's add that to the props here so it's validation schema and it was called advanced schema so now that that schema has those fields we need to actually add that to our formic form so the username will be blank the job type will be empty as well and then accepted tos will be false by default okay so now that that's in we go back to this form i'll just clear the console when this is empty we should have an error state in our input and here it is and here's that error message we defined so now let's go back to our input and we need to add a class name so that we we can display the input in an error state when there's an error so for the class name we're going to check the meta info we're going to see if it's been touched and whether there's an error if it's been touched and there's an error we're going to give it this class otherwise it'll be empty so it's the same kind of logic as before and then below this we're going to want to add some helper text and that's going to display our error message so this is going to check for those same two things and if they're true meaning there's an error it's just going to display a div with the actual error message and pass an error class which will just make it uh red for the text so if we go back we can now see that and when we satisfy the form it goes away so this text and field input is is done and the next one that we want to do is the custom select so let's go to the components folder and add our custom select we'll call this custom select and it's going to be very similar to our custom input so i'm just going to copy and paste that and in here instead of this being an input it's just going to be a select and again we're going to get the label pass that in pass in the formic field props which will have those functions and it's going to work the exact same way so now let's go and we'll actually change this to custom select and now let's go back to our form and import that so in here we want to pass some props again and we'll give it a label and we could say job type and then we also need to give it a name and the name we defined is here job type and lastly a placeholder and we just need to import this at the top and now if we hit save we should see that in our app here so this is in an air state because we haven't given any options to the select so let's add those and i'm just going to paste those in so now all of these options are going to be children of this custom select which is going to be a label and this select element here so all these values i'll close that out all these values developer designer manager that's what we defined in our schema right here so these are the only valid options so that's what that value has to be and the default option is going to be just an empty string that says please select a job so if we hit save we should see please select a job and when we select a valid one the area goes away so that's it for our select and now we just need to add our checkbox so let's go under components and create a file called custom checkbox and this is going to be very similar to our custom input so let's just copy and paste that over and we'll rename it and now instead of displaying a label we are just going to do a span and we could say i accept the terms of service and now i want to wrap this in a div and we'll give it a class name of checkbox and that's just for styling purposes and the class name here and this error message is the same from all the other components and again we're taking this checkbox input and we're spreading out those props that we received from formic so we can come in here and import that and we want to pass it some props so the first thing is the type and we want a type of checkbox and the next thing is the name and remember in our formic state has to be the same so we'll just copy that over and hit save now if we go back here we should see this checkbox and these fields should all work and then when we submit we haven't actually defined a submit handler so let's go back and define that so the first thing is in our format component we need to grab that on submit prop and i'm going to paste in a function it's the same one that we used before and this is just going to wait for one second and call the reset form helper method and let's just pass in this on submit so now we should be able to submit the form and it clears all the inputs and the last thing i want to change is this button right now it just stays the same when we submit but i want it to be blurred out so it tells the user that the form is submitting and in the props here we remember we get access to the form and the form state and that would include when the form is being submitted so we can destructure is submitting and then come down to our button and we want this to be disabled when is submitting is true so now if we hit save and go back fill out our form you should see this button blurred out when it's submitting that's pretty much it for this video i know it's kind of a long one but i hope it was helpful and that you guys learned something so thank you guys so much for watching and please hit that like button if you enjoyed and subscribe if you haven't already it would help me out tremendously so thanks again and i'll see you guys in the next one [Music] you
Info
Channel: Nikita Dev
Views: 85,679
Rating: undefined out of 5
Keywords: javascript, react, react forms, formik, formik tutorial, react formik, react formik tutorial, react form tutorial, react form validation, formik and yup tutorial, formik validation, react form with validation, yup validation, yup tutorial, yup validation tutorial
Id: 7Ophfq0lEAY
Channel Id: undefined
Length: 34min 50sec (2090 seconds)
Published: Sat May 07 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.