警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控制(或反之亦然)。决定在组件的生命周期内使用受控或不受控制的输入元素。
我的代码:
constructor(props) {
super(props);
this.state = {
fields: {},
errors: {}
}
this.onSubmit = this.onSubmit.bind(this);
}
....
onChange(field, e){
let fields = this.state.fields;
fields[field] = e.target.value;
this.setState({fields});
}
....
render() {
return(
<div className="form-group">
<input
value={this.state.fields["name"]}
onChange={this.onChange.bind(this, "name")}
className="form-control"
type="text"
refs="name"
placeholder="Name *"
/>
<span style={{color: "red"}}>{this.state.errors["name"]}</span>
</div>
)
}
答案 0 :(得分:131)
原因在于您定义的状态:
android:elevation="5dp"
字段作为空白对象,因此在第一次呈现this.state = { fields: {} }
期间将this.state.fields.name
,输入字段将获得以下值:
undefined
因为输入字段将变得不受控制。
在输入中输入任何值后,状态中的value={undefined}
将更改为:
fields
此时输入字段会转换为受控组件,这就是您收到错误的原因:
组件正在更改文本类型的不受控制的输入 控制。
可能的解决方案:
1-将this.state = { fields: {name: 'xyz'} }
状态定义为:
fields
2-或者使用Short-circuit evaluation来定义value属性,如下所示:
this.state = { fields: {name: ''} }
答案 1 :(得分:17)
除了接受的答案,如果您使用的是input
或checkbox
类型的radio
,我发现我需要对{{1 }}属性。
checked
如果您使用的是TS(或Babel),则可以使用无效合并而不是逻辑OR运算符:
<input
id={myId}
name={myName}
type="checkbox" // or "radio"
value={myStateValue || ''}
checked={someBoolean ? someBoolean : false}
/>
答案 2 :(得分:10)
将value
更改为defaultValue
即可解决。
注意:
defaultValue
仅用于初始加载。 如果要初始化input
,则应使用defaultValue
,但如果要使用state
来更改值,则需要使用value
。阅读this了解更多信息。
我使用了value={this.state.input ||""}
中的input
来消除该警告。
答案 3 :(得分:4)
在组件内部,以以下方式放置输入框。
<input className="class-name"
type= "text"
id="id-123"
value={ this.state.value || "" }
name="field-name"
placeholder="Enter Name"
/>
答案 4 :(得分:3)
简单,您必须先设置初始状态
如果您未设置初始状态,则react会将其视为不受控制的组件
答案 5 :(得分:2)
如果在字段中使用多个输入,请遵循: 例如:
class AddUser extends React.Component {
constructor(props){
super(props);
this.state = {
fields: { UserName: '', Password: '' }
};
}
onChangeField = event => {
let name = event.target.name;
let value = event.target.value;
this.setState(prevState => {
prevState.fields[name] = value;
return {
fields: prevState.fields
};
});
};
render() {
const { UserName, Password } = this.state.fields;
return (
<form>
<div>
<label htmlFor="UserName">UserName</label>
<input type="text"
id='UserName'
name='UserName'
value={UserName}
onChange={this.onChangeField}/>
</div>
<div>
<label htmlFor="Password">Password</label>
<input type="password"
id='Password'
name='Password'
value={Password}
onChange={this.onChangeField}/>
</div>
</form>
);
}
}
在以下位置搜索您的问题:
onChangeField = event => {
let name = event.target.name;
let value = event.target.value;
this.setState(prevState => {
prevState.fields[name] = value;
return {
fields: prevState.fields
};
});
};
答案 6 :(得分:2)
如果该值不存在或为空,则输入空值。
value={ this.state.value || "" }
答案 7 :(得分:1)
首先设置当前状态...this.state
这是因为当您要分配新状态时,它可能未定义。因此也可以通过设置状态提取当前状态来解决该问题
this.setState({...this.state, field})
如果您的状态中有一个对象,则应按以下方式设置状态, 假设您必须在用户对象内设置用户名。
this.setState({user:{...this.state.user, ['username']: username}})
答案 8 :(得分:1)
使用 React Hooks 也不要忘记设置初始值。
我使用的是<input type='datetime-local' value={eventStart} />
,最初的eventStart
就像
const [eventStart, setEventStart] = useState();
代替
const [eventStart, setEventStart] = useState('');
。
括号中的空字符串是不同的。
另外,如果像我一样在提交后重置表单,则再次需要将其设置为空字符串,而不仅是空括号。
这只是我对该主题的一小部分贡献,也许会对某人有所帮助。
答案 9 :(得分:1)
未定义输入字段值时引发此问题的原因是发出警告。如果您为多个输入字段创建一个changeHandler,并且想要使用changeHandler更改状态,则需要使用点差运算符分配先前的值。就像我的代码在这里。
constructor(props){
super(props)
this.state = {
user:{
email:'',
password:''
}
}
}
// This handler work for every input field
changeHandler = event=>{
// Dynamically Update State when change input value
this.setState({
user:{
...this.state.user,
[event.target.name]:event.target.value
}
})
}
submitHandler = event=>{
event.preventDefault()
// Your Code Here...
}
render(){
return (
<div className="mt-5">
<form onSubmit={this.submitHandler}>
<input type="text" value={this.state.user.email} name="email" onChage={this.changeHandler} />
<input type="password" value={this.state.user.password} name="password" onChage={this.changeHandler} />
<button type="submit">Login</button>
</form>
</div>
)
}
答案 10 :(得分:0)
如上所述,您需要设置初始状态,就我而言,我忘记在 setSate() 中添加 ' ' 引号;
const AddUser = (props) => {
const [enteredUsername, setEnteredUsername] = useState()
const [enteredAge, setEnteredAge] = useState()
出现以下错误
正确的代码是简单地将初始状态设置为空字符串 ' '
const AddUser = (props) => {
const [enteredUsername, setEnteredUsername] = useState('')
const [enteredAge, setEnteredAge] = useState('')
答案 11 :(得分:0)
我在使用 react hooks 时遇到了同样的警告, 虽然我之前已经将初始状态初始化为:-
const [post,setPost] = useState({title:"",body:""})
但后来我在 onChange 事件处理程序上覆盖了预定义状态对象的一部分,
const onChange=(e)=>{
setPost({[e.target.name]:e.target.value})
}
解决方案 我通过首先处理前一个状态的整个对象(通过使用扩展运算符)然后在其上进行编辑来解决这个问题,
const onChange=(e)=>{
setPost({...post,[e.target.name]:e.target.value})
}
答案 12 :(得分:0)
喜欢这个
value={this.state.fields && this.state.fields["name"] || ''}
为我工作。
但我这样设置初始状态:
this.state = {
fields: [],
}
答案 13 :(得分:0)
更改此
const [values, setValues] = useState({intialStateValues});
为此
const [values, setValues] = useState(intialStateValues);
答案 14 :(得分:0)
可以应用多个方法:
constructor(props) {
super(props);
this.state = {
value:''
}
}
<input type='text'
name='firstName'
value={this.state.value}
className="col-12"
onChange={this.onChange}
placeholder='Enter First name' />
[value, setValue] = useState('');
<input type='text'
name='firstName'
value={value}
className="col-12"
onChange={this.onChange}
placeholder='Enter First name' />
HOC.propTypes = {
value : PropTypes.string
}
HOC.efaultProps = {
value: ''
}
function HOC (){
return (<input type='text'
name='firstName'
value={this.props.value}
className="col-12"
onChange={this.onChange}
placeholder='Enter First name' />)
}
答案 15 :(得分:0)
警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换为受控制(反之亦然)。在组件的生命周期中决定使用受控还是不受控制的输入元素。
解决方案:检查值是否未定义
React / Formik / Bootstrap / TypeScript
示例:
{ values?.purchaseObligation.remainingYear ?
<Input
tag={Field}
name="purchaseObligation.remainingYear"
type="text"
component="input"
/> : null
}
答案 16 :(得分:0)
就我而言,这几乎就是Mayank Shukla的最高回答所说的。唯一的细节是我的州完全缺乏我所定义的财产。
例如,如果您具有以下状态:
state = {
"a" : "A",
"b" : "B",
}
如果要扩展代码,则可能要添加一个新的道具,因此,可以在代码的其他地方创建一个新属性c
,其值不仅在组件状态上未定义,而且该属性也未定义自身未定义。
要解决此问题,只需确保将c
添加到您的状态并为其指定适当的初始值即可。
例如
state = {
"a" : "A",
"b" : "B",
"c" : "C", // added and initialized property!
}
希望我能够解释我的极端情况。
答案 17 :(得分:0)
const [name, setName] = useState()
在文本字段中键入就会生成错误
const [name, setName] = useState('') // <-- by putting in quotes
将解决问题