Check out a free preview of the full Introduction to the JAMStack course:
The "Handling Input State with Hooks" Lesson is part of the full, Introduction to the JAMStack course featured in this preview video. Here's what you'd learn in this lesson:

Jason continues to build the app by using React, demonstrates that hooks manage the different states of the form, and explains how to use a curried function to update the different fields within the form.

Get Unlimited Access Now

Transcript from the "Handling Input State with Hooks" Lesson

>> The next thing that we wanna do is make this form, do things. So we're gonna do a little bit of state management with React. This is something that is increasingly more important is apps get more and more interactive. If you are not a React developer, again, you can kind of like this is all important to the example but feel free to just check out this code once I have done it, if you don't care about learning React.

[00:00:33] So lemme start up our server again. And what I want here is, I want to be able to manage the state. So I'm gonna set up what I want the form state to be. And because it's a like a default value, I'm gonna give it a big all caps name to signify like, hey, this is a constant, it's not gonna change.

[00:00:56] It's not a transient value. And inside of it, I wanna set up what the values are. So the name, email, subject, and body. And they all start empty. Then, we need to define how to actually manage that data. So how do we wanna update this stuff. And we're gonna use a concept called a Reducer.

[00:01:19] The reason that we're gonna do that is that it would be a big pain to have independently tracked state. If we wanted to reset, we'd have to call four different functions to reset each of these to be empty. So instead, we're gonna do something where we treat the whole state, this initial state, as a single value.

[00:01:37] And we can perform different actions on it based on what we send in. So the way that a Reducer works is, we define a function called a Reducer. And then that Reducer gets the current state and then an action and that action is defined by us. And the standard way to approach this is to use a switch statement.

[00:01:58] As you've been learning code, you may have seen like switch statements are a bad thing, I think switch statements are great, they are perfectly applicable way to solve a problem. And in this particular case, I think that they are the right tool for the job. So a standard way to set up an action is to have it set up with a type.

[00:02:21] And that would be a string of some sort. And then, you can pass in anything you want. So any arbitrary value. And so, like maybe we wanna, no, you got to stop using FUBAR. I don't know why I keep doing that. If we wanted to say like name and put in a name, that might be the action that we send in.

[00:02:42] And so I would say on action type of do stuff, then I can access this name and do something with it. So what I'm gonna do is I'm going to set up my switch. And then on a case of update field value, that'll be what we give our type name.

[00:03:00] I want to return a new state. And so the state is gonna be whatever the initial state was, and then I'm gonna update the field that I send in, so I'm gonna give a field name. And then I'm going to put in whatever the new value is. And so our object is going to look, it'll have field and then the name of the field we wanna update.

[00:03:23] One of these name, email, subject, body, and then we'll set it to a value. And that will replace whatever empty string is here. And then by default, if we get an action that we don't recognize, we're just gonna bail out and we will return the initial state. So with our initial state and our Reducer, we are now able to have React, start managing our state for us and React introduced something called the Hooks a little while back and one of the Hooks they give us is actually called use Reducer.

[00:04:02] Prior to React hooks, the Reducer pattern was really popular in state management libraries like Redux. And for the vast majority of React developers who've worked on large apps, there's a decent chance you've crossed paths with Redux. And I think that if you haven't used the Reducer pattern in hooks, this is gonna be a nice breath of fresh air because it takes a lot of the complexity out.

[00:04:28] So the first thing I'm gonna do is import the use Reducer hook from React. And this use Reducer hook is going to allow us to fire up this Reducer. So I'm going to say I want the state and a dispatcher. So a dispatcher is how you send an action to a Reducer.

[00:04:52] The state is initially this INITIAL_STATE, or whatever gets returned from the Reducer. And the dispatcher is how we actually call this. So let's just code one up and it'll become a little more clear. So I'm gonna say I wanna use the Reducer. And the Reducer I wanna use is the one that we just defined.

[00:05:13] And the initial state is what we'll put in here. So I've got my Reducer setup that gives us our state and our dispatch, and that means I can go in here and start adding these values. So if I go into my input class name and, let me turn that route back on, and I setup a value of

[00:05:40] So that's gonna be up here Then what we should see is that, This stopped working, right? It's now what we call a controlled input, because we're setting the value explicitly through React, which means that we need a way to update that value. And that's how we're gonna use this Reducer.

[00:06:03] So let's write a handler for handling any input change. And I'm gonna call this update field value, and we're gonna use another fun computer-sciencey term called Currying. Has anybody ever curried functions before? So this is, it's not as scary as it sounds, I promise. So what it means is, instead of calling a function with two arguments, we call it with the first argument and then return another function that accepts the second argument, and that means we can call our functions in stages.

[00:06:34] So what the default setup might be is to sa,y hey, let's call update field value with the field and the value, and then do some stuff with it. And that would be great. But the catch is that then we would have to write a pretty serious function in here for each one to set up the field name and then get the event value and pass it in.

[00:06:57] And that's a lot of duplicate work. So what we can do instead is we can start by saying we want to pass in the field name. And then, once we have the field name return a function that'll accept the value and then send both of those to the Reducer.

[00:07:14] So it's a way for us to simplify the boilerplate a little bit by just making our functions callable in stages instead of needing to be called all at once. And what I wanna do is I actually want to take the event that happened, so when we call on change, and this is whenever something changes in the input, so you type in it, that will trigger this event.

[00:07:37] And I can say update field value. And the field name that I wanna use is name. And so what this does is now I'm gonna call updateFieldValue with name, and what it will return is this function. So we called it with name, and now we've got one function that accepts an event.

[00:07:55] And this is gonna look familiar, like a regular event handler, right? But we still have access to this field name. So that means that we can put all of our logic for updating the field into this one curried function. And the way that that will actually work is we're going to dispatch an event or would dispatch an action.

[00:08:16] The type of that action, if we remember is updateFieldValue. And what I want to send in is the field name, which we've already got. So I'm just gonna let that auto expand. If you don't include a value, the variable will give its self its name, and then its value as a default.

[00:08:37] And then we wanna include the new value. And the new value is going to be the event target value. And the way that this works is that, when you have an event, they get sent through an input. The target is going to be this input, so I'm going event target to get to the input, and then I want the value of that input.

[00:09:01] So whatever I just typed, that's going to be reset. So now that I've done this, what we should see is that when I save, now I can type again, right. It's not exciting in and of itself. But what's really nice about this is that if I do something like, let's say whenever the state changes, I think this will work.

[00:09:34] I might be. So I've got my state here. And it gives us our body name, and then whenever I change it, it will update in the state. So now, the state object is tracking those values for us in a way that's a little more manageable than having to update five independent variables with five independent function calls.

[00:09:57] So there's a little more setup to make it work. But there is a big payoff in reduced complexity for managing this stuff. So what I'm gonna do is I do wanna log this. So when we get our, when we submit the form I wanna log the state. So I can save that.

[00:10:20] Let's make this a little bit shorter, and then let's just give it a try. Okay, so that's what we want, we're getting the state whenever we submit the front, perfect. So let's add the rest of these values to make them controlled. And I'm going to do that by, effectively just copy pasting.

[00:10:41] So we'll do state email. And on change, it's going to be update field value, email. So let's grab these. Put them down on the subject and then, change those. And one more on the body. Okay, so now we have each of these is a controlled input, which means that I should be able to set up all of my stuff, Send it, so now we get our form input as a value that we can use.

[00:11:25] So our state is fully managed now. And that means that we are able to send it to our contact function, our serverless function that we need to write. And so, if you didn't wanna write the React stuff and you didn't wanna write styles now it'd be a good time to pull from the FEM-progress branch.

[00:11:42] So that you're up to date with where we are when we move into the serverless function stuff.