Issue 1:
Since I can not re-open other's issue, I am opening this issue to address a potential type check issue that is causing a lot unexpected behavior on other issues.

After viewing the source code and confused by handleStateChange rename to onParentShouldUpdate; onCheck rename to handleCheck then rename to onSwitch and massive unifying code on the EnhancedSwitch,

I think my recent project found the root of this issues. ( I really think the source code need to refactor a bit to read it easier.

//sorry for the complaining but it is really confusing and hard to keep track of the function name

Root of the problem

Applying on onCheck() usually cause an setState() on the owner Element

This will also trigger a render() lifecycle event on the owner Element

In React when Owner render() it triggers the componentWillReceiveProps() on its child, in our case the <Checkbox />

In the componentWillReceiveProps

componentWillReceiveProps(nextProps) {
this.setState({
switched: this.props.checked !== nextProps.checked ?
nextProps.checked :
this.state.switched,
});
}

Normally if onCheck() and checked are provided the update looks like this

input.onChange(event) => EnhancedSwitch.handleChange(event) =>
EnhancedSwitch.onSwitch(event, isInputChecked) === Checkbox.handleCheck(e, v) === Checkbox.onCheck(e, v) =>
Owner.onCheck(v) => Owner.setState() => Owner.render() =>
Checkbox.componentWillReceiveProps() => Checkbox.setState({switched:nextProps.checked}); =>
Checkbox.render() => EnhancedSwitch.componentWillReceiveProps() =>
EnhancedSwitch.setState(switched: nextProps.checked) => input.value = isInputChecked

But If onCheck() is provided but no check or value provided Checkbox lifecycle event becomes

componentWillReceiveProps(nextProps) {
this.setState({
switched: this.props.checked !== nextProps.checked ? // undefined !== undefined => always false
nextProps.checked :
this.state.switched,
});
}
=> this.setState({switched: this.state.switched});

this is a duplicate setState that we did not anticipate. Since we do not provide a check props to the Checkbox, the Checkbox should be the state container for EnhancedSwitch and handle its own state, but Owner.render() is called in the same call stack this.setState() inside Checkbox.handleStateChange.

So the actual render we get is the

this.setState() inside Checkbox.handleStateChange

and

this.setState() inside Checkbox.componentWillReceiveProps

batched together.

A fix should not be a setTimeout( () => this.setState() on the Owner. Checkbox nor EnhancedSwitch

It should be a simple type check inside the componentWillReceiveProps

componentWillReceiveProps(nextProps) {
if(nextProps.checked !== undefined) {
this.setState({
switched: this.props.checked !== nextProps.checked ? nextProps.checked : this.state.switched
});
}

setTimeout simply change the order of the render and setState;

Checkbox.handleStateChange(event, true);

//normal setState
Checkbox setState({switch:true}) Finished
Owner setState() Finished
Owner rendering
Checkbox componentWillReceiveProps
Checkbox state: false => Checkbox setState({switch:false});
//React auto batched two setState() then render
Checkbox rendering
EnhancedSwitch rendering

//setTimeout setState
Checkbox setState() Finished
Owner setTimeout setState() Finished //push setState() to event loop out of the current call stack
Checkbox rendering() //on rendering the Checkbox state updated
EnhancedSwitch rendering() //this prioritized Checkbox setState() => render() to run next
Owner rendering() //current stack is empty, next call in event loop is Owner
Checkbox componentWillReceiveProps
Checkbox state: true => Checkbox setState({switch:true});
Checkbox rendering()
EnhancedSwitch render()

If you want to learn more about the eventloop and setTimeout hack

Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014

This is a really good video explaining what is happening.

one note on controlled component

Only if you set the value of the input, it should be considered as a controlled component. For example, if I ever want to use google analytic to true my input actual usage I should only need to track it with onCheck rather than turn it into a controlled component.

And allowing onCheck without making it a controlled component makes it skips tons of parent update.

In my case I render 30 check box as a feature list and I don't want my Owner component to render every time a checkbox change but only match the state to the selected. This allows me to skip Array.map many times and I notices this reduce the visual response time at least by 300ms.

This library needs a lot performance and lifecycle hook refactoring. And this should be a good start.

I am pretty new to how to open a PR or anything, but I will try it when I have time.

If you read this comment and understand the reason I think it should be a bugfix without changing anything else.

Or we could discuss the state of switch and how to remove the setState in WillReceiveProps, this is a typical A implies B does not imply B implies A design issue.

We should enforce a single source of truth, either as a state at top level component then the child will only use props as the source or as the actual value in the DOM input which need to connect with the correct lifecycle event to map to a state.

Related and could correctly closed issue:

Checkboxes and toggles issue

Checkbox not updating

[Checkbox] setting the state in onCheck doesn't display the checked box

Related PR:

[Toggle][Checkbox] setting the state in onCheck doesn't display the checked box

fix [Toggle][Checkbox] setting the state in onCheck doesn't display the checked box

Issue 2:
Setting the state in the callback of onCheck event cancels the [V] mark on the selected box.

Without setting the state, the checkbox works as expected.

Working fine

<Checkbox
label="price"
onCheck={this._handleCBPrice.bind(this)} />
_handleCBPrice(event, checked){}

Doesn't mark the box with a [V]

<Checkbox
label="price"
onCheck={this._handleCBPrice.bind(this)} />

_handleCBPrice(event, checked){
this.setState({someKey:someValue})
}