Support a state change handler for all control props

InstructorKent C. Dodds

Share this video with your friends

Send Tweet

In our simple situation, having an onToggleChange handler is sufficient because the on state is the only state we have, but in a more complex component, there could be many items of state. We could make an prop callback for each of those items of state, but that could drastically increase the complexity and repetition of our component. Instead, let's make an onStateChange that's called when any state changes.

Nesta Xu
Nesta Xu
~ 3 years ago

This line of code wouldn't work anymore: <code>this.props.onToggle(this.getState().on)</code>, because when it is invoked in the callback of <code>setState</code>, the state object returned from <code>this.getState()</code> will not contain the "recommended" changes for the control props. Only the internally managed state will have the changes reflected at that point in time, but not the control props.

That means that <code>onToggle</code> of this component wouldn't be passed the "toggled" value.

We may want to either get rid of <code>onToggle</code>, or pass <code>onToggle</code> handler <code>allChanges.on</code> instead of <code>this.getState().on</code>.

So it may look like this: <code>(allChanges) => { this.props.onToggle(allChanges.on) }</code>, and in the callback of <code>setState</code>, invoke <code>callback(allChanges)</code>

Kent C. Dodds
Kent C. Dodds(instructor)
~ 3 years ago

Nesta, that sounds reasonable to me 👍

Webmaster Mortgages
Webmaster Mortgages
~ 3 years ago

How does the code in the lesson work, if in the video you have a typo {{changed}} (see line 34) all the way down to the end?.. I see that source code doesn't have this typo, though.

Kent C. Dodds
Kent C. Dodds(instructor)
~ 3 years ago

Whoops! Nice catch! The reason it works despite the typo is because changes is always a function in this simple example.

Viktor Soroka
Viktor Soroka
~ 2 years ago

How do you propose to manage multiple states in that onStateChange passed to toggle? A bunch of if statements inside it to handle each one? Now it only has one on state which does not show the problem of multiple ones.

Kent C. Dodds
Kent C. Dodds(instructor)
~ 2 years ago

I'm not sure what you mean, but downshift uses this pattern with 4 elements of state and it works really well. Maybe that'll help answer your question?

Mauro Carrero
Mauro Carrero
~ 10 months ago

Great stuff. The callback in toggle would not be necessary anymore, right? when removing it we'd need to validate callback presence and type in internalSetState before invoking it.

toggle = () => {
    this.internalSetState(
      ({on}) => ({on: !on})
    )
  }