Setting a checkbox "check" property in React
Amoebe's answer is correct, but I think there's a cleaner solution than the double bank (!!
). Simply add a defaultProps property with value false
for checked
prop of your Checkbox component:
import React from 'react';
const Checkbox = ({checked}) => (
<div>
<input type="checkbox" checked={checked} />
</div>
);
Checkbox.defaultProps = {
checked: false
};
export default Checkbox;
Basically, the defaultChecked
means you don't want to control the input – it just renders with this value and then there is no way to control it. Also, value
shouldn't be used, but checked
instead, so your second code should be correct. And you shouldn't use them both simultaneously.
<input
type="checkbox"
checked={this.state.checked}
onChange={this.onChangeAction.bind(this)}
/>
Can you create a small fiddle with this behaviour?
The problem arises if you set the checked
property of your checkbox to null
or undefined
.
Those are a "falsy" values in JS, however React treats a value of null
as if the property was not set at all. Since the default state of a checkbox is unchecked, everything will work fine though. If you then set checked
to true
React thinks the property suddenly comes into existence! This is when React figures you switched from uncontrolled to controlled, since now the prop checked
exists.
In your example you can get rid of this warning by changing checked={this.settings[setting]}
to checked={!!this.settings[setting]}
. Notice the double bang (!!
). They will convert null
or undefined
to false
(and leave true
alone), so React will register your checked
property with a value of false
and start off with a controlled form component.
I had this problem too and I, too, read the docs about controlled-components several times to no avail, but I finally figured it out, so I thought I'd share. Also, since version 15.2.0 normal inputs are triggered to be controlled by setting value
, while checkboxes are initialized as controlled by setting checked
, regardless of their value
property, which added a bit to the confusion.