Form elements should be either controlled or uncontrolled
- REACT_MISUSED_CONTROLLED_COMPONENT
- Error
- Medium
- react
This rule applies when a form element such as <input>
, <textarea>
, and <select>
works as both controlled and uncontrolled element.
The followings are controlled elements whose values are controlled by React state and associated handler functions:
- A form element has
value
prop. <input>
element of typeradio
orcheckbox
haschecked
prop.
In contrast, the followings are uncontrolled elements with the initial values:
- A form element has
defaultValue
prop. <input>
element of typeradio
orcheckbox
hasdefaultChecked
prop.
Therefore, a form element should not have both value
and defaultValue
props. Also, <input>
element should not have both checked
and defaultChecked
props. React outputs a warning message if you set both props for a form element.
Noncompliant Code Example
View with compliant examples side by sideimport React from 'react';
export class FormExample extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('The submitted value: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} defaultValue="DeepScan" onChange={this.handleChange} /> {/* REACT_MISUSED_CONTROLLED_COMPONENT alarm because 'input' element should be either controlled or uncontrolled. */}
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Compliant Code Example
View with noncompliant examples side by sideimport React from 'react';
export class FormExample extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'DeepScan'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('The submitted value: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Version
This rule was introduced in DeepScan 1.8.0-beta.
See
React Warning: FormExample contains an input of type text with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://fb.me/react-controlled-components