Javascript 一个组件正在将一个不受控制的文本类型输入更改为 ReactJS 中的受控错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47012169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:42:37  来源:igfitidea点击:

A component is changing an uncontrolled input of type text to be controlled error in ReactJS

javascriptreactjs

提问by Riya Kapuria

Warning: A component is changing an uncontrolled input of type text 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.*

警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控制(反之亦然)。决定在组件的生命周期内使用受控或非受控输入元素。*

Following is my code:

以下是我的代码:

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>
  )
}

回答by Mayank Shukla

The reason is, in state you defined:

原因是,在您定义的状态下:

this.state = { fields: {} }

fields as a blank object, so during the first rendering this.state.fields.namewill be undefined, and the input field will get its value as:

字段作为空白对象,因此在第一次渲染期间this.state.fields.name将为undefined,并且输入字段将获得其值:

value={undefined}

Because of that, the input field will become uncontrolled.

因此,输入字段将变得不受控制。

Once you enter any value in input, fieldsin state gets changed to:

在 input 中输入任何值后,fields状态将更改为:

this.state = { fields: {name: 'xyz'} }

And at that time the input field gets converted into a controlled component; that's why you are getting the error:

那时输入字段被转换为受控组件;这就是您收到错误的原因:

A component is changing an uncontrolled input of type text to be controlled.

组件正在更改要控制的文本类型的不受控制的输入。

Possible Solutions:

可能的解决方案:

1- Define the fieldsin state as:

1- 将fields进入状态定义为:

this.state = { fields: {name: ''} }

2- Or define the value property by using Short-circuit evaluationlike this:

2- 或者使用像这样的短路评估来定义 value 属性:

value={this.state.fields.name || ''}   // (undefined || '') = ''

回答by MoFoLuWaSo

Changing valueto defaultValuewill resolve it.

更改valuedefaultValue将解决它。

Note:

注意

defaultValueis only for the initial load. If you want to initialize the inputthen you should use defaultValue, but if you want to use stateto change the value then you need to use value. Read thisfor more.

defaultValue仅用于初始加载。如果要初始化,input则应使用defaultValue,但如果要使用state更改值,则需要使用value. 阅读本文了解更多信息。

I used value={this.state.input ||""}in inputto get rid of that warning.

我曾经value={this.state.input ||""}input摆脱这一警告的。

回答by Tabish

Inside the component put the input box in the following way.

在组件内部按以下方式放置输入框。

<input className="class-name"
              type= "text"
              id="id-123"
              value={ this.state.value || "" }
              name="field-name"
              placeholder="Enter Name"
              />

回答by Vaibhav Bacchav

SIMPLY, You must set initial state first

很简单,您必须先设置初始状态

If you don't set initial statereact will treat that as an uncontrolled component

如果您不设置初始状态,react 会将其视为不受控制的组件

回答by Lynden Noye

In addition to the accepted answer, if you're using an inputof type checkboxor radio, I've found I need to null/undefined check the checkedattribute as well.

除了接受的答案之外,如果您使用的inputcheckboxor类型radio,我发现我还需要 null/undefined 检查checked属性。

<input
  id={myId}
  name={myName}
  type="checkbox" // or "radio"
  value={myStateValue || ''}
  checked={someBoolean ? someBoolean : false}
  />

And if you're using TS (or Babel), you could use nullish coalescing instead of the logical OR operator:

如果您使用 TS(或 Babel),您可以使用空合并而不是逻辑 OR 运算符:

value={myStateValue ?? ''}
checked={someBoolean ?? false}

回答by NuOne

Set Current State first ...this.state

首先设置当前状态 ...this.state

Its because when you are going to assign a new state it may be undefined. so it will be fixed by setting state extracting current state also

这是因为当您要分配一个新状态时,它可能是未定义的。所以它将通过设置状态提取当前状态来修复

this.setState({...this.state, field})

If there is an object in your state, you should set state as follows, suppose you have to set username inside the user object.

如果你的状态中有一个对象,你应该如下设置状态,假设你必须在用户对象中设置用户名。

this.setState({user:{...this.state.user, ['username']: username}})

回答by Nelles

const [name, setName] = useState()

generates error as soon as you type in the text field

一旦您在文本字段中输入就会产生错误

const [name, setName] = useState('') // <-- by putting in quotes 

will fix the issue on this string example.

将解决此字符串示例的问题。

回答by Hamidreza Rafiei

If you use multiple input in on field, follow: For example:

如果您在字段中使用多个输入,请遵循:例如:

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>
     ); 
  }
}

Search your problem at:

在以下位置搜索您的问题:

onChangeField = event => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState(prevState => {
        prevState.fields[name] =  value;
        return {
            fields: prevState.fields
        };
    });
};

回答by Dr. Malte Westerloh

I am getting the same warning: A component is changing an uncontrolled input of type hidden to be controlled. I cannot fix my problem. Any ideas why?

我收到了同样的警告:一个组件正在改变一个隐藏类型的不受控制的输入来控制。我无法解决我的问题。任何想法为什么?

export default ({  valueName, onChangeAllg,}) => {

          <TextField
            id={"name"}
            select
            label={"name"}
            value={valueName.geschlecht || ""}
            name={"name"}
            onChange={onChangeAllg}

          >
            {nameList.map((option) => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>

i tryed ({ valueName, valueName: {geschlecht=""}, onChangeAllg,})and value={valueName.geschlecht || ""}

我tryed({ valueName, valueName: {geschlecht=""}, onChangeAllg,})value={valueName.geschlecht || ""}

回答by user3706761

Warning: A component is changing an uncontrolled input of type text 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.

警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控制(反之亦然)。决定在组件的生命周期内使用受控或非受控输入元素。

Solution : Check if value is not undefined

解决方案:检查值是否未定义

React / Formik / Bootstrap / TypeScript

React / Formik / Bootstrap / TypeScript

example :

例子 :

{ values?.purchaseObligation.remainingYear ?
  <Input
   tag={Field}
   name="purchaseObligation.remainingYear"
   type="text"
   component="input"
  /> : null
}