EDIT: this question was marked as a duplicate by some users. Not sure if they read it before doing so. If someone did, please clarify in which sense this is a duplicate.
I have a component for checkboxes:
class Checkbox extends Component {
onChange = (e) => {
if (this.props.input) {
this.props.input.onChange(e.target.checked);
} else if (this.props.onChange) {
this.props.onChange(e.target.checked, this.props.id);
}
};
render() {
const { input, value, className, label } = this.props;
let inputValue = (input && input.value) || value;
return (
<div className={'Checkbox' + (className ? ' Checkbox--' + className : '')}>
<input
className="Checkbox-input"
type="checkbox"
onChange={this.onChange}
checked={inputValue}
/>
<span className="Checkbox-helper" />
<span className="Checkbox-label" htmlFor="">
{label}
</span>
</div>
);
}
}
This component returns an error when the value changes.
Warning: A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
But if I replace:
let inputValue = (input && input.value) || value;
with
let inputValue = value;
if (input) {
inputValue = input.value;
}
Like so:
class Checkbox extends Component {
onChange = (e) => {
if (this.props.input) {
this.props.input.onChange(e.target.checked);
} else if (this.props.onChange) {
this.props.onChange(e.target.checked, this.props.id);
}
};
render() {
const { input, value, className, label } = this.props;
let inputValue = value;
if (input) {
inputValue = input.value;
}
return (
<div className={'Checkbox' + (className ? ' Checkbox--' + className : '')}>
<input
className="Checkbox-input"
type="checkbox"
onChange={this.onChange}
checked={inputValue}
/>
<span className="Checkbox-helper" />
<span className="Checkbox-label" htmlFor="">
{label}
</span>
</div>
);
}
}
It doesn't return any error. Why?
One possibility—there's not enough information here to say for sure—is that input.value
is present but false
(or falsy), so you fall back to the value
prop, which is undefined
, and you end up setting checked
to undefined
on your input.
This results in an uncontrolled checkbox.
Then, on a subsequent pass, either input.value
or props.value
has changed and you set checked
to a real value, which means it's now a controlled input and react emits the warning.
In your initial case you'll get the value
prop even if input.value
is explicitly false
or 0
or an empty string:
// if input.value === false here you get
// the fallback value which may be undefined
let inputValue = (input && input.value) || value;
In your modified case…
let inputValue = value;
if (input) {
inputValue = input.value;
}
…you've avoided that scenario because you're predicating it on the presence of input
itself rather than input.value
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.