Advanced React Patterns State Reducer Component & Exercise
This course still contains valuable patterns in React, but doesn't cover React Hooks introduced in React 1.16.
Transcript from the "State Reducer Component & Exercise" Lesson
>> Kent C. Dodds: State reducer, one of my favorite patterns ever, I love this pattern. So this is actually, incidentally this is a common pattern in React redux or sorry react reason, reason-react, that's what it's called. So like all components have this concept of a state reducer. I discovered it, I didn't invent it, but I discovered it trying to solve a problem in downshift where people needed to be able to control state but in a simpler way than control props which we'll learn about later.
[00:00:38] But a state reducer, if I render prop is responsible or enables users to control how things are rendered. A state reducer enables people to control how the logic works, how the state is managed and so it actually has nothing to do with Redux. The only similarity is the fact that the API for your reducer is a reducer like function state and then your changes.
[00:01:08] But other than that, it's just reducer is a computer science topic, not Redux thing. So, here's the problem that we're trying to solve, let's pop open the state reducers examples. So, here we've got this situation where I wanna be able to control how many times somebody clicks. They can't click more than four times, if they do, I'll say well, you clicked too much, I will disallow any more changes until you say reset, and then I will let more happen, okay?
[00:01:40] Try again, it's like no, you clicked too much. So that's what we're trying to do, we're trying to jump into the toggle and say hey, based on my own state I don't want you to update your state after this certain point or I want to control how you're updating your state.
[00:01:57] So the implementation of this is a little intrusive on how you implement the toggle component. You have to think more critically about how you're updating state, because now the internal state of your component is actually part of the API that you're providing. Because you want people to be able to control how that state's being updated.
[00:02:17] So it kinda breaks encapsulation, some of these things, but what it allows is a huge amount of flexibility from the user standpoint. So a little extra complication on implementation side, allowing for an enormous amount of flexibility on the user side is a win for me. Especially if that means the alternative would be even more complication on the implementation side anyway.
[00:02:43] So, let's look at the code for how this is being used. It's a little bit bigger of a usage example. So this usage has some state, keeps track of how many times you're clicking. And we have an on toggle handler, handleToggle, that will update the state, incrementing the times clicked.
[00:03:06] And then, yeah, just this handle reset that doesn't really matter for your specific use cases here, and then the toggleStateReducer. So this is the reducer function that people are gonna be passing to you and you need to call this before you actually set state. Okay, so toggle accepts that state reducer prop, and it's going to call the function with all of the state, the current state of the toggle, and then the proposed changes.
[00:03:35] So these are the things, I'm updating the on state from true to false. And so like what this will look like is on is true when it's called. And so then inside of this state reducer, we gonna say, okay if on my own stake, if they have clicked more than or equal to 4 times, then I'm gonna let you finish, but first I want to make sure that the on state never changes from false.
[00:04:09] So feel free to update any other state that you have internally, but the on state should never change from false. It should always be false. And your toggle components is gonna continue the state stuff and it's gonna use this to set the state instead. And then it'll, yeah, the on state will never change from false until this says it's okay to do that.
[00:04:33] So one tip is, because this needs to have, in our case right here we don't actually need the state. But some toggle state reducers might need to reference some other pieces of state. So this is why it's a state reducer, is it accepts the false state object and the changes.
[00:04:53] So because it needs to have the current state of the toggle component, you're gonna need to call this function within a set state updater. So you'll say this.set State, updater function and within that function you'll call this state reducer, so you can pass the full state shape or object.
[00:05:15] Okay, and all those changes are gonna need to happen right in here, in a new function you'll create and then you'll make some updates to existing code.