组件正在更改ReactJS中要控制的文本类型的不受控制的输入错误

Riy*_*ria 167 javascript reactjs

组件正在更改要控制的类型文本的不受控制的输入.输入元素不应从不受控制切换到受控制(或反之亦然).决定在组件的使用寿命期间使用受控或不受控制的输入元素.

我的代码:

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

May*_*kla 329

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

this.state = { fields: {} }
Run Code Online (Sandbox Code Playgroud)

为空白对象字段,以便在第一渲染this.state.fields.nameundefined,并且输入字段将获得价值为:

value={undefined}
Run Code Online (Sandbox Code Playgroud)

因为输入字段将变得不受控制.

在输入中输入任何值后,fields状态变为:

this.state = { fields: {name: 'xyz'} }
Run Code Online (Sandbox Code Playgroud)

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

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

可能的解决方案:

1-将fieldsin状态定义为:

this.state = { fields: {name: ''} }
Run Code Online (Sandbox Code Playgroud)

2-或者使用如下的短路评估来定义value属性:

value={this.state.fields.name || ''}   // (undefined || '') = ''
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你,这对我有用:`value={this.state.fields.name || ''}` (8认同)
  • 我不知道一旦值变得未定义,输入就会自动变得不受控制,太棒了。已经解决我的问题了 (6认同)
  • 惊人的!因为我没有在官方文档中看到这一点,还是我瞎了?请链接到来源:) (4认同)
  • 是否有未定义的原因是“不受控制的”而后者是“受控的”-这是什么意思? (2认同)
  • 因为`''是有效的字符串值。因此,当您将“''`更改为“ xyz”时,输入类型不会更改,即表示将控制方式更改为受控方式。但是,如果从“未定义”到“ xyz”类型,则类型将从不受控制变为受控。 (2认同)

Tab*_*ish 35

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

<input className="class-name"
              type= "text"
              id="id-123"
              value={ this.state.value || "" }
              name="field-name"
              placeholder="Enter Name"
              />
Run Code Online (Sandbox Code Playgroud)


Lyn*_*oye 29

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

<input
  id={myId}
  name={myName}
  type="checkbox" // or "radio"
  value={myStateValue || ''}
  checked={someBoolean ? someBoolean : false}
  />
Run Code Online (Sandbox Code Playgroud)

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

value={myStateValue ?? ''}
checked={someBoolean ?? false}
Run Code Online (Sandbox Code Playgroud)


小智 27

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

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


小智 25

发生这种情况是因为该值不能为未定义或 null 来解析,您可以这样做

value={ this.state.value ?? "" }
Run Code Online (Sandbox Code Playgroud)


Ain*_*riu 15

如上所述,您需要设置初始状态,在我的例子中,我忘记在 setSate(); 内添加 ' ' 引号;

  const AddUser = (props) => {
  const [enteredUsername, setEnteredUsername] = useState()
  const [enteredAge, setEnteredAge] = useState()
Run Code Online (Sandbox Code Playgroud)

给出以下错误

在此输入图像描述

正确的代码是简单地将初始状态设置为空字符串 ' '

  const AddUser = (props) => {
  const [enteredUsername, setEnteredUsername] = useState('')
  const [enteredAge, setEnteredAge] = useState('')
Run Code Online (Sandbox Code Playgroud)

  • 原来是这个错误!!多谢。 (2认同)

Nel*_*les 10

const [name, setName] = useState()
Run Code Online (Sandbox Code Playgroud)

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

const [name, setName] = useState('') // <-- by putting in quotes 
Run Code Online (Sandbox Code Playgroud)

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


Hea*_*ity 10

解决此问题的最佳方法是将初始状态设置为''

constructor(props) {
 super(props)
  this.state = {
    fields: {
      first_name: ''
    }
  }
  this.onChange = this.onChange.bind(this);
}

onChange(e) {
  this.setState({
    fields:{
     ...this.state.fields,
     [e.target.name]: e.target.value
    }
  })
}


render() {
  return(
    <div className="form-group">
      <input
        value={this.state.fields.first_name}
        onChange={this.onChange}
        className="form-control"
        name="first_name" // Same as state key
        type="text"
        refs="name"
        placeholder="Name *"
      />
      <span style={{color: "red"}}>{this.state.errors.first_name}</span>
    </div>
  )
} 
Run Code Online (Sandbox Code Playgroud)

if (field)然后,如果您的值为 ,您仍然可以像这样运行检查,并且仍然获得相同的结果''

现在,由于您的值现在被分类为字符串类型 ,而不是评估后未定义的类型。因此,从控制台中清除了一个大红色块的错误。


小智 8

更改valuedefaultValue将解决该问题。

注意事项

defaultValue仅用于初始负载。如果要初始化,input则应该使用defaultValue,但是如果要使用state来更改值,则需要使用value。阅读更多。

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

  • 谢谢你!我遇到了这个问题,其他解决方案不适用于我,但这个解决方案有所帮助。 (5认同)

小智 7

我是reactjs新手,我正在使用reactjs版本17,我遇到了这个问题

我解决了:

而不是这个

const [email, setEmail] = useState();
Run Code Online (Sandbox Code Playgroud)

我添加了这个

const [email, setEmail] = useState("");
Run Code Online (Sandbox Code Playgroud)

在 useState 函数中,我添加了引号来初始化数据,错误消失了。


NuO*_*One 6

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

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

this.setState({...this.state, field})
Run Code Online (Sandbox Code Playgroud)

如果您的状态中有一个对象,则应按如下所示设置状态,假设您必须在用户对象中设置用户名。

this.setState({user:{...this.state.user, ['username']: username}})
Run Code Online (Sandbox Code Playgroud)


小智 5

如果该值不存在或为 null,则输入空值。

value={ this.state.value || "" }
Run Code Online (Sandbox Code Playgroud)


and*_*eda 5

如果您将value属性设置为对象的属性并希望确保该属性不是未定义的,那么您可以将空合并运算符??与可选链接运算符结合使用?.,如下所示:

<input
  value={myObject?.property ?? ''}
/>
Run Code Online (Sandbox Code Playgroud)