Current section: Control Props 30 exercises
lesson

Intro to Control Props

Loading lesson

Transcript

00:00 I know that the one-liner for control props looks kind of long, but let me say it even faster. Control props is the value prop on an input. That's it. So when you have an input or like a checkbox with the checked prop, or a select, you've got a value prop there,

00:18 and then you have an on-change prop, that is what makes up the control prop pattern, and it's just us implementing it ourselves. So here's the one-liner. The control props pattern allows users to completely control state values within your component. Then maybe this could be like a separate thing, because that's not really a one-liner.

00:38 So here's why this is a little bit longer than one line. This differs from the state reducer pattern in the fact that you can not only change the state changes based on actions dispatched, where like in our state reducer, oh, a thing happened, let's decide what we're going to do about it. You can not only do that with control props,

00:58 but you can also trigger state changes from outside the components or hook as well. So you can imperatively, or not really necessarily imperatively, but you get to control when those state changes happen. You can make state changes happen that didn't actually weren't triggered inside the component. That's the idea of control props,

01:16 and that's how it differs from state reducers. So while state reducers still super valuable, sometimes component libraries won't implement the state reducer pattern because they support control props and that's more powerful anyway. In my view, I think having both is really valuable,

01:32 but control props can allow you to do what state reducers do plus more. It's just a little bit more work on the user of your component. So let's talk about control props. Here's my capitalized input. We've got a value, we have an onChange here. We're setting the capitalized value to the uppercase version of the value.

01:50 So the reason that this is controlled is because we're programmatically changing the state value. So as you're typing in here, it's uppercase even though you didn't type uppercase. Maybe you make your users mad for that reason. But here's another example.

02:06 We can synchronize two inputs based on or by using the control prop. So we're controlling the value for each of these. One is capitalized and one is lowercase, and we're keeping those two states separate here, and then in our handleInputChange,

02:24 it's actually handling the change for both of them. We update both of them to be whatever the current value is for the one that changed. So allowing you to control the value of one input, even though that input isn't the one that changed. That's the idea behind control props.

02:43 It just allows the external user to control some internal state. Just like state reducers, this means that you're exposing your internal state as part of your API through the props that you are providing here, and that's fine. It's just something to keep in mind.

03:01 There are a number of libraries that implement this. In fact, most of them do. Downshift, of course, implements control props, so you can control the isOpenState, selectedItem, inputValue, and highlightedIndex. Probably the most important aspect of all of this is that for

03:19 each one of these, you get an onChange callback. So when there's a change inside the state, you'll get notified via the onStateChange callback, and so that way, you can say, okay, the internal library says, I would change it if I was in charge, but because you provided the control prop,

03:38 you are in charge and I'm just going to do whatever you say. So that's the idea behind control props. The same thing with radix, it also has the ability to say, hey, here's what the value should be, here's my callback. So when the value changes, tell me what you would have changed it to,

03:55 and I will change it if I want to, if I decide. So the way that this is actually implemented differs. I like to provide more information in my onChange handler where some will just provide, here's the value that changed. But I think knowing more information can be really helpful, like why did it change, how did it change?

04:15 And so I typically will provide more information than just this is the value that it changed to. Okay, with all that said, I think we're ready to go through this and implement it. The last thing that I will mention is that you can, you'll notice that if you change the control value

04:35 on a controlled input, that React will give you a warning. So if you start out with undefined and then you give it a string later, React's like, hey, you changed from uncontrolled to controlled, like which is it you got to choose? And you can absolutely implement that yourself. We are not doing that in this exercise because it's a whole other thing,

04:51 and it's really not critically important for your understanding of this particular pattern. But that's another thing that I thought I'd mention, because you will see that sometimes in libraries that they will track whether you start as controlled and switch to uncontrolled or vice versa and give you a warning, that can be helpful.

05:09 Something maybe you could work on extra for extra credit if you want to. Okay, with all that said, I think you're ready for the exercise. Let's get started.