This course has been updated! We now recommend you take the React Performance course.

Check out a free preview of the full State Management in Pure React, v2 course:
The "setState & Function" Lesson is part of the full, State Management in Pure React, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates that different objects can be passed into setState, and focuses on the case of passing in a function. A function within a state can be useful when adding complicated logic to a growing application because it can be called multiple places while following the DRY principle.

Get Unlimited Access Now

Transcript from the "setState & Function" Lesson

>> There's also a little bit more to this.setState. So traditionally we saw we were passing an object in, turns out, you can pass other stuff in. In this case, you can pass a function in there as well. So this is an interesting one. This looks very similar to the example we had before.

[00:00:17] But now you can see, I can pass in a function. And that function gets some arguments, the first of which being state. And that gets passed into the function and then we can do stuff with it. So this looks similar to the one before. But if we use this syntax, anyone want to take a lucky guess what the counter is gonna be incremented to?

[00:00:42] Three, right? Cuz in this case, it is not necessarily batching them, cuz before we could merge objects, right? Sometimes the like squirreliest parts of managing state in React, have nothing to do with React and everything to do with JavaScript, right? You can merge objects, you can't merge functions.

[00:00:58] That's not a thing, right? You can compose them, let's not get into it, there's, yeah. But you can go ahead and you can, it'll play through each one of those functions one by one. So place the first one. Okay that went from zero to one, it played to the second one that went from one to two, play to the third one that went from two to three, we'll go three times to that point.

[00:01:17] So, using a slightly different syntax gives you some wildly different effects, wild for a counter but you can imagine that in a lecture situation, it could be where it's like, I like this new syntax. I'm just gonna, some of the worst bugs that I've ever introduced a new code base, which is I'm influencing some other feature.

[00:01:35] I'm just gonna refactor this while I'm in here, all right? That always goes real well. Cool, so we can implement it like this we can do state.count, if you really want you could destructure it and make it count + 1, it doesn't really matter, these are two different ways of saying the same thing.

[00:01:54] Either way we go whichever syntax you like more, go for it, it doesn't matter. So yeah, like I said, it plays through each of them. And this allows you to do some interesting things as well. Because it's a function, not just an object, we can write some rules as well.

[00:02:11] We can go ahead and we can say like, all right only increment up to five, you know if it's already greater than equal to five return otherwise do this, right? So this will give us a counter that only goes up to five in this case. And you can have all sorts of different kind of like logic.

[00:02:26] This becomes a little bit more interesting when you want to pass stuff in, right, if you're hard coded and you could have just done it in the render function, so on and so forth, but we can go ahead and be able to pass in. So let's actually play with this counter a little bit now that we have it.

[00:02:41] So, we'll go into the code, and let's just try out what we kinda saw on the screen a second ago. We'll say this.setState. Let's give it a function this time. We'll say state, and in this case we'll do if state.count is greater than or equal to 5 we'll just return.

[00:03:05] And I'll pause for a moment, you'll notice that I could go ahead and I could say like count is state.count, I could say update the state to what it already was But I can also if I return undefined from this function effectively, it will just not update the state.

[00:03:23] One of the reasons that I'm calling that to your attention is because like that won't work later, right? So this is kind of what you know, in storytelling is like if there's like a gun used in chapter 14, it better be on the mantelpiece in chapter one. And if there's a gun on the mantelpiece in chapter one, it better be used in chapter 14, right?

[00:03:39] So I'm pointing this out now because like we will talk about it again in a little bit. So we'll say if state.count is greater than 5, just return otherwise, All right, so we'll try the simplest version of this. We'll go ahead and check it out in the application increment increment increment.

[00:04:04] And you can see I can still hit the button but we're not going past five. All right, this is cool. Now this becomes a little bit more interesting if we wanna pass in some kind of prop. So for instance, we could go over into application and we could say, all right, counter, we'll say that you have a max of 5.

[00:04:24] We'll say 15. And we'll say a step of 5, right? So we can pass in additional data. All right, so we've passed in a max of 15 and a step of 5. And the most obvious thing to do in this case, would do something like, Max and step = this.props.

[00:04:57] And we could say, all right, if it's less than or equal to the max, or if it is, and then we'll increment by the step. Let's take that for a spin and make sure to make any fatal mistakes. 5, 10, 15 no more, right? Now, one of the things Is that if this got a little bit more complicated, right, this function that was doing all this logic, really, even one standard deviation more complicated, there might be a world that we wanted to test in, right?

[00:05:31] I know, wild. We might want to run a unit test. Now, with all this.props and this.state, that becomes a little bit tricky because then we gotta pull out either enzyme or React testing library. We've got a mountain component, and we've got to pass in props. And then we've got all that stuff.

[00:05:48] Right when we're just trying to test like, does this function work the way that we think it should? Right? So it turns out that on top of just getting state, it also gets. Props, and so we could actually do that all within the function. Since that this.props is going to be the props.

[00:06:11] Now, a careful eye will note that this is really just a function, like a regular function we can do anything with, right? So I could, theoretically, pull this out. We could have it somewhere else where it's a regular old JavaScript function. You could theoretically some state and some props, right, and then look at the return value that comes out.

[00:06:37] And just write a very, very, very simple unit task, cuz it's just a JavaScript function, and then we could pass it in here. This is also useful if you find yourself in an application that's growing, and you're like, okay, I have some of this complicated logic and then we're using in multiple places, right?

[00:06:53] Which leaves you to two choices right at multiple places, which is a violation of any kind of like principle that you've ever heard of, right? Because then you also have to remember to change it multiple places. Or you can just kind of break it out and then have one thing that you could use multiple places.

[00:07:07] Like for our editors, we have like, you know, everyone thinks that there's like a code editor and design editor. There's really 12 editors for all the different places that you might use them. And they're kind of composed of all these different pieces. And so we can just change one place and get it across all the things.

[00:07:22] It's, you know, building out these small building blocks rather than having a bunch of conditionals and a large editor. Right, so everything works just as it did before. But here we've pulled everything out. And that's one of the kind of big advantages to being able to use a function in this.state, right?

[00:07:39] We can have it. We can test it super easily without having to mount the entire component, so on and so forth. Right, and we saw if we do it three times, it will stack up and so it behaves a little bit differently. So when you go into like, I like this pattern, I'm going to refactor, right, like that can get a little bit problematic because if we did, It will run through it all three times.

>> The arrow function would replace the need for this.increment.bind, right?
>> So we've got one called increment that's just kind of its own separate one that's separate outside of the class.
>> Okay.
>> There is a syntax that you can use when you do this.
>> That's it, yeah.

>> This, depending on the day is not natively supported in browsers, right? So what this does it's an arrow function that's effectively doing the same as this. It requires a bubble plug in which you may or may not have in your application. And if you just yeah, pasted, it is not natively supported.

[00:08:45] And there is an argument that this will define a new function in every class instance versus the other one was shared on the superclass. I don't necessarily care about that, cuz when we get the hook, so we're gonna be redefining functions all over the place. It's more the issue of one, you might not have that in your application, right, because it's not natively supported.

[00:09:05] That said, one of the first things we do when we're setting up a project to Twilio is we install that plugin, that's what we do. Or we did, now we just use hooks. But yeah, so that'll work, too. Great question.
>> Thanks for the refresh.
>> Yeah, no problem.