Use Component State Initializers

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet
Published 4 years ago
Updated a year ago

In this lesson, we'll allow users to initialize our component's state with their own defaults and support a reset functionality to reset to the initial state.

Instructor: [00:00] Often when you have a render prop API, it could be really useful to be able to reset the state to the initial state from within the component. In our case, we have this reset button. That reset button is bound to an on-click for reset. We're going to expect that from our state and helpers that we're passing to our children in the toggle render prop API.

[00:20] We'll also expect to have an on reset prop called. In our case, that's just going to log to the console. Let's go ahead and implement this. We're going to add a reset arrow function here. This will simply call this set state with on is false. That's our initial state there.

[00:39] As a callback, it will call this.props.onresetthis.state.on. Next, we'll come down here and add that to our get state and helpers, which we're calling our render prop API with. The reset is this.reset. With that, if we pop open the console, we click toggle on, we see that console log, and then we click reset. It resets us to the original state, and logs on reset false.

[01:04] There's one other consideration here, and that is a reset handler is not necessarily required. Let's go ahead and add static default props. On reset is just an empty arrow function.

[01:17] With a simple toggle component, it's not a huge deal to duplicate this initial state here. I don't like that, because if I were to add some state here, I'd have to remember to add that state here. In a scenario where the state object is a little bit bigger, duplicating that code is not optimal.

[01:32] What I like to do is I will create a initial state object that will have my on as false. Then it will assign state to this.initialstate. With that, I can call set state with this.initialstate, and that works just fine.

[01:49] In addition to this, it's a pretty common scenario where you want people to be able to initialize the state to whatever state that they want. In this use case, we want to be able to provide an initial on prop so we can initialize the on state.

[02:01] Let's go ahead and rather than on is false, we can say on is this.props.initialon. Then users can specify the initial on to be true, and it initializes as true. Then if we toggle it off and click reset, then it'll reset to that initial state.

[02:20] Because this is not a required prop either, let's go ahead and add a default. We'll say initial on is false, and then if this prop is not provided, it will initialize to false. This is the state initializer's pattern. As a helper, we can also reset to that initial state.

Wix
Wix
~ 4 years ago

Hi, Can you elaborate about the case where Toggle is re-rendered with a different value for initialOn?

Erez erezm@wix.com

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

If it's re-rendered with a different value for initialOn then I would consider that to be a mistake on the user's part. If they want to actually change the value that the component gets reset to they can either use a key prop to force react to unmount and remount a new instance, or they can use control props.

Thein
Thein
~ 3 years ago

if multiple buttons with combine behaviors, how will you manage it? For example onoff button plus reset state button?

Thein
Thein
~ 3 years ago

I got it; I can use switch statement at getTogglerProps and use id;

Ann
Ann
~ 3 years ago

Hi, I am confused why you are not using the constructor(props) method to set the initial state. Is this a style preference or is there a benefit to setting it the way you have in this example?

Kent C. Dodds
Kent C. Doddsinstructor
~ 3 years ago

We're using public class fields. Learn more about them here: https://egghead.io/lessons/react-use-class-components-with-react and here: https://egghead.io/lessons/javascript-public-class-fields-with-react-components

Thein
Thein
~ 3 years ago

Ann, if you use babel transpiler, at your project root .babelrc file, you can set plugins :["transform-class-properties"]