How React Hooks Change The Way We Build Forms

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we're in the middle of building a new react project and we want users in it to be authenticated so we've created this register form it consists of an email and a password input and restoring the values typed into these inputs in our local state the problem is that when we type into these inputs users can provide whatever they want and when the forms submitted those values are going to be accepted to make sure these email and password values are actually valid we need to do validation and there's a number of ways that we could approach this we could for example bring in a third-party library such as the library Formik if we take a look at their docs we see it consists of bringing in a Formik component to use it we need to provide some validation rules on a prop and then form it gives us back a bunch of stuff that we can passed our form and validate its inputs now this is an acceptable approach the only question is do we really need to bring in a third party library to do validation is that necessary to add that additional weight to our project on top of that do we need to change the structure of our component tree you see that our form is now nested within this function this render props function and it's in turn nested in another component I'm going to show you an easy way to do validation in your react apps that doesn't involve bringing in a third-party library it doesn't involve changing the shape of your form components or you can just grab the things that you need to do validation and this is a pattern that you can reuse across your react projects we're gonna do this with the help of a custom react hook so let's head back to our project and you can follow along with me by grabbing the starting code by going to this link I'll include it in the description and if we take a look at our project files we see that there is in source a file called use form validation this is where our custom hook is going to live so we'll begin by bringing it into our index.js file our main file import use form validation from the file of the same name and we're gonna execute it up at the top of register now we're gonna bring over all the functionality of formic or any other form library and the first step will be to move over our state so we want use form validation to take care of our state will no longer have it locally so let's create within our hook a new piece of state will call you state up at the top and we'll call this state variable values and the setter will be set values to make this reusable we want the ability to provide any number of state values not just two as we have here but you know three or more the way that we can do this easily is using an object we'll only need to provide one object here and we can have any number of different properties so let's model the state that we want to put in our hook let's model the initial state so let's create a variable called initial state set it equal to an object and pass in the initial values of email and password which are both an empty string then to pass our state to our hook we'll provide it as an argument and then back in our hook we'll call that parameter initial state and make that the value of our values state variable but now the question is how are we going to update this values state object well previously if we take a look at our inputs we see that we're using individual setter set email and set password when there was a change event when a user typed into these inputs but again for our reusable hook since we don't know what setters we'll need to have let's make a generic function let's reference a handle change function for both of these we haven't created it yet and let's make handle change within our hook so handle change we'll get access to the change event then to update our state we need to call set values the first part of updating an object with the use state hook is that we need to spread in with the object spread operator the previous values so we're spreading our previous values object into this new object that we're updating it with and then we need to take the values that are typed into each of our inputs and put it in the appropriate property so to make sure that's the case we have this name attribute this name prop that for each input corresponds to the property we want we want to update so for the email input the name is set to email and for the password input name is set to password which aligns with that property so with that done we can take from the change event event dot target dot name to get the name of the input that's being typed in currently and we'll set that property to event the target dot value to get the value that was typed in and we use these brackets surrounding event target name to dynamically change the property that we're updating but at this point handle change is still not being made available to register register doesn't know anything about handle change so to pass it to register we need to return it from our hook and we'll return it on an object since we're going to need to provide a number of things to register so we'll pass it as a property and value then we can when we execute our hook D structure from the object that we're returning so using this syntax we are able to provide handle change to both of our inputs and at this point we can effectively remove both of our individual state values the only problem is that we're going to be told that we don't have an email or a password instead we're going to need to make available the entire values object to our register component so we'll do we'll follow the exact same process that we did with handle change and now the email value is going to come from values got email and for password that will be I used up password and since we were previously using a controlled component the values of the was for being controlled by state the value prop for both of them it's going to be set to values on email and values not password so now we're back to our previous state, our previous situation where we can type into both these inputs hit submit and we see that we're keeping track of these form values in our state but we're still not validating our form so let's see how Formik does this for example with the validate function it takes the values that are stored in state and then it basically creates an errors object then it checks the state values and see if it meets a certain condition so in this case it's checking to see if there actually is an email value provided and if not it's going to put a message required on this new property email this message is important because it's going to be what we show to our users in our UI when there's an error so we'll tell them that email is required and then finally at the end we're going to return that errors object so let's just copy this entire validate function I'll include the link to the formic documentation so you can grab this and then we'll go to a new file that's called validate auth so this is going to be our validate function it'll accept our state values and let's paste in what we copied we'll remove the arrow function here I'll just write this as a function declaration and right now we have a couple of conditionals for email the email needs to be required and it needs to be a valid email but what about the password input well let's add another conditional for the password errors so this will be up at the top email errors so let's add another if-else for our first conditional say if not value stop password if there is no password provided we're going to add to the heirs object a password property and set that to the message required actually we can say required password and for email will say required email then we'll add an else if for another condition and we'll check to see that our password is a certain length and we can do that by taking values password dot length and we'll see for example if it's at least six characters so we can say if that's less than six then we want to add to our password property password must be at least six characters so now that we've specified all these conditions let's actually use our validate auth function first we need to bring it into index touch a s just like we did our hook and just like initial state we want to pass validate auth as a second argument and we'll call this parameter within our hook function call it the validate so this will be the validate function and we can pass in whatever validation that we want so we want validation to occur when the form submitted so now we can bring over the handle submit function we no longer need it within our register component and we'll put it within our hook and make sure to return it we see that our form is now being much more decoupled much more lean you could say to the point where we are only really having to return markup from it and all of our logic is within our hook so now that we have handles submit we want to do the validation before we say that the user is authenticated so here we're going to execute the validate function pass in values and we're gonna get back an errors object which we'll call validation errors so there's a couple of steps that we could take here we could add some additional logic within handles submit to say you know if there are any errors then we can reject submission and display the errors however what if we have another handler what if we have another point where we want validation to be executed for example when a user clicks away from an input we call that a blur event so let's say we have a function called handle blur well instead of putting the logic just in handle submit and needing to then duplicate our code what we'll do is we'll take this line where we're validating our state and then we'll create a piece of errors state or the setter will be set errors and initially that's going to be an object it's going to hold our errors object and we want a way to look at State and see if this errors object has changed whenever it's updated and the way to conveniently do that is with the use effect hook so let's create use effect above our handle change and as the second argument we'll provide an array that consists of our dependencies meaning when we want to execute this function here so we'll specify as our dependency errors when errors and state changes they want to call this function and in this function will then figure out when our user should be authenticated versus when the error should be displayed first we need to check to see if our forms been submitted so let's create an is submitting piece of state the setter will be set submitting and initially this will be false when the form submitted however right after we call validate we want to set submitting to true then within use effect we'll check to see if the forms been submitted if is submitting is true then we'll need to check to see if the user should be successfully authenticated or if we should show our errors and the way we'll do this is by checking to see if there are any errors on this state object there's no easy way to count the number of properties on a given object so what we can do is we can turn this object into an array with objects ease we put the keys or properties of this object into an array and we can measure the length using the length property of arrays and we'll check to see if it's 0 and if that's the case then we can say we have no errors so if there are no errors then we want to authenticate our user so for now let's just include our console.log and we want to stop submission of the form after that soul set submitting to false and if we do have errors else if there are errors then we want to display the air is on that object and that'll be done simply by passing errors back to our register component so all we need to do here is set submitting to false as well and that's it all we really need to do at this point is pass all the necessary values and functions back to register and that now includes handle blur as well as errors and is submitting so we can just copy this entire object here and the structure all the values back in index is we can add handle blur to both of the inputs with the on blur prop and also to indicate to our user that there was an error we can do a couple of things we can make the border of both of these inputs red to indicate there was a problem and also we can put the error message underneath them so for the email input we'll set the class name we'll check to see if there's from errors from the errors object if there's an email error and if that's the case we'll use the and conditional to say we want to append the class error input I've created this class for you behind the scenes that will make our border red and we can do the same for our password input check to see if than air if there's an error coming from aerospace word and then for our messages we can interpolate under both of the inputs a conditional where if we have an email error we're going to return a set of paragraph tags and in them get our message from errors dot email and we'll give it the class error text and we can copy that and do the same for errors password and then the very last step to make sure that we're not able to submit our form multiple times when it's being validated or when it's processing will disable the submit button by using the disabled prop and that's going to be set according to is submitting so let's test this out when we select an input and then blur away from it oh and I forgot to include set errors and pass validation errors to our state when we select an input and then blur away from it we see both of our error messages appear now if we provide an email but it's not valid we get invalid email address as our message so let's fix that and for our password if we don't provide a long enough password we'll be told it needs to be at least six characters and when we do that our errors go away and we can successfully submit our form now to test out how good our custom hook is we're going to use it within the context of a real-world project I brought in firebase here into a separate file I brought in firebase as a dependency so now within our hook instead of just console logging at the end of handle submit let's configure exactly how we want our users to be authenticated by passing in a third argument which will be an authenticate function so let's create this function within index dot js we'll call it authenticate user and I'll just need to bring in firebase then I'll grab the values from state, i'll destructure them name and password then I'll set up a try/catch I'll try to out then I get the user by saying firebase dot register pass in email and password and since this returns a promise we can make this function async and await this register process so we'll try to do that if that's not successful we'll catch any errors first with a console err say there's an off air pass through the air object and then in order to catch any server-side errors where we might pass our client-side validation the authentication may not be successful on the server side to be able to display that error message we can add a new piece of error state which we'll call firebase air etc will be set firebase error and initially this will be null and here we'll set firebase error if there is one pass in the message from air dot message and then underneath the password error message we'll check to see if we have a firebase error and in that case we're gonna return another set of paragraph tags this time the text is going to come from the firebase air that we have stored and finally to pass through that authentication function as a third argument will provide authenticate user and then within our hook we'll call this parameter authenticate and now instead of just console logging authenticated here will actually execute our authenticate function just like that so now if we provide some values that pass our client-side validation but don't correspond to an actual user on our server when we hit submit you see a split second later we get the message telling us that the password is invalid or the user doesn't have a password so with that we have a custom form validation hook that give basically all the functionality of a form library like formic and with it we didn't have to change the shape of our form hardly at all except for adding the values that we needed we saw how you could use it in a real-world project today and we were able to add it and around 50 lines of code thanks for watching if you're interested in more hooks content be sure to subscribe I'll be coming out with a lot more in the near future I've got some really exciting stuff coming up soon that includes both react hooks as well as firebase if you want to learn all the major concepts of using react hooks be sure to check out my course react hooks it'll show everything that you need to know about them from front to back I'll include the link in the description or you can head to code artistry IO thanks again for watching and I'll catch you in the next video
Info
Channel: Web Dev Hero
Views: 72,398
Rating: undefined out of 5
Keywords: How React Hooks Change The Way We Build Forms, how react hooks change the way we build forms, react hooks forms, react hooks build forms, react hooks form validation, react hooks form state, react custom hooks, react hooks global state, react hooks useeffect, react hooks usestate, react form validation, react hooks formik, react hooks form input, react hooks login, react hooks input, react hooks onsubmit, react formik, react final form hooks, react, react hooks, reactjs, context
Id: 8yo44xN7-nQ
Channel Id: undefined
Length: 19min 50sec (1190 seconds)
Published: Sun May 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.