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.
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>
Nesta, that sounds reasonable to me 👍
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.
Whoops! Nice catch! The reason it works despite the typo is because changes
is always a function in this simple example.
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.
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?
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})
)
}