Javascript React - 更改不受控制的输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37427508/
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 20:18:55  来源:igfitidea点击:

React - changing an uncontrolled input

javascriptnode.jsreactjsreact-state

提问by alexs333

I have a simple react component with the form which I believe to have one controlled input:

我有一个简单的反应组件,我认为它具有一个受控输入的形式:

import React from 'react';

export default class MyForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <form className="add-support-staff-form">
                <input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
            </form>
        )
    }

    onFieldChange(fieldName) {
        return function (event) {
            this.setState({[fieldName]: event.target.value});
        }
    }
}

export default MyForm;

When I run my application I get the following warning:

当我运行我的应用程序时,我收到以下警告:

Warning: MyForm 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

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

I believe my input is controlled since it has a value. I am wondering what am I doing wrong?

我相信我的输入是受控的,因为它具有价值。我想知道我做错了什么?

I am using React 15.1.0

我正在使用 React 15.1.0

回答by fvgs

I believe my input is controlled since it has a value.

我相信我的输入是受控的,因为它具有价值。

For an input to be controlled, its value must correspond to that of a state variable.

对于要控制的输入,其值必须对应于状态变量的值。

That condition is not initially met in your example because this.state.nameis not initially set. Therefore, the input is initially uncontrolled. Once the onChangehandler is triggered for the first time, this.state.namegets set. At that point, the above condition is satisfied and the input is considered to be controlled. This transition from uncontrolled to controlled produces the error seen above.

在您的示例中最初不满足该条件,因为this.state.name最初未设置。因此,输入最初是不受控制的。一旦onChange第一次触发处理程序,this.state.name就会被设置。此时,满足上述条件,输入被认为是受控的。这种从不受控制到受控制的转变产生了上面看到的错误。

By initializing this.state.namein the constructor:

通过this.state.name在构造函数中初始化:

e.g.

例如

this.state = { name: '' };

the input will be controlled from the start, fixing the issue. See React Controlled Componentsfor more examples.

输入将从一开始就受到控制,从而解决了问题。有关更多示例,请参阅React Controlled Components

Unrelated to this error, you should only have one default export. Your code above has two.

与此错误无关,您应该只有一个默认导出。你上面的代码有两个。

回答by Leigh Brenecki

When you first render your component, this.state.nameisn't set, so it evaluates to undefinedor null, and you end up passing value={undefined}or value={null}to your input.

当您第一次渲染您的组件时,this.state.name未设置,因此它评估为undefinedor null,并且您最终将value={undefined}or 传递value={null}给您的input.

When ReactDOM checks to see if a field is controlled, it checks to see if value != null(note that it's !=, not !==), and since undefined == nullin JavaScript, it decides that it's uncontrolled.

当 ReactDOM 检查某个字段是否受控制时,它会检查是否value != null(注意它是!=,不是!==),并且由于undefined == null在 JavaScript 中,它决定它是不受控制的。

So, when onFieldChange()is called, this.state.nameis set to a string value, your input goes from being uncontrolled to being controlled.

因此,当onFieldChange()被调用时,this.state.name设置为字符串值时,您的输入将从不受控制变为受控制。

If you do this.state = {name: ''}in your constructor, because '' != null, your input will have a value the whole time, and that message will go away.

如果您this.state = {name: ''}在构造函数中这样做,因为'' != null,您的输入将始终具有值,并且该消息将消失。

回答by JpCrow

Another approach it could be setting the default value inside your input, like this:

另一种方法是在输入中设置默认值,如下所示:

 <input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>

回答by Muhammad Hannan

I know others have answered this already. But a very important factor here that may help other people experiencing similar issue:

我知道其他人已经回答了这个问题。但是这里有一个非常重要的因素可以帮助遇到类似问题的其他人:

You must have an onChangehandler added in your input field (e.g. textField, checkbox, radio, etc). Always handle activity through the onChangehandler.

您必须onChange在输入字段中添加一个处理程序(例如 textField、checkbox、radio 等)。始终通过onChange处理程序处理活动。

Example:

例子:

<input ... onChange={ this.myChangeHandler} ... />

When you are working with checkboxyou may need to handle its checkedstate with !!.

当您使用复选框时,您可能需要checked使用!!.

Example:

例子:

<input type="checkbox" checked={!!this.state.someValue} onChange={.....} >

Reference: https://github.com/facebook/react/issues/6779#issuecomment-326314716

参考:https: //github.com/facebook/react/issues/6779#issuecomment-326314716

回答by MUSTAPHA GHLISSI

Simple solution to resolve this problem is to set an empty value by default :

解决这个问题的简单方法是默认设置一个空值:

<input name='myInput' value={this.state.myInput || ''} onChange={this.handleChange} />

回答by Greg R Taylor

One potential downside with setting the field value to "" (empty string) in the constructor is if the field is an optional field and is left unedited. Unless you do some massaging before posting your form, the field will be persisted to your data storage as an empty string instead of NULL.

在构造函数中将字段值设置为 ""(空字符串)的一个潜在缺点是,如果该字段是可选字段并且未进行编辑。除非您在发布表单之前进行一些按摩,否则该字段将作为空字符串而不是 NULL 持久保存到您的数据存储中。

This alternative will avoid empty strings:

这种替代方法将避免空字符串:

constructor(props) {
    super(props);
    this.state = {
        name: null
    }
}

... 

<input name="name" type="text" value={this.state.name || ''}/>

回答by KARTHIKEYAN.A

When you use onChange={this.onFieldChange('name').bind(this)}in your input you must declare your state empty string as a value of property field.

当您onChange={this.onFieldChange('name').bind(this)}在输入中使用时,您必须将状态空字符串声明为属性字段的值。

incorrect way:

不正确的方法:

this.state ={
       fields: {},
       errors: {},
       disabled : false
    }

correct way:

正确方法:

this.state ={
       fields: {
         name:'',
         email: '',
         message: ''
       },
       errors: {},
       disabled : false
    }

回答by Menelaos Kotsollaris

In my case, I was missing something really trivial.

就我而言,我错过了一些非常微不足道的东西。

<input value={state.myObject.inputValue} />

<input value={state.myObject.inputValue} />

My state was the following when I was getting the warning:

当我收到警告时,我的状态如下:

state = {
   myObject: undefined
}

By alternating my state to reference the input of my value, my issue was solved:

通过改变我的状态来引用我的 value 的输入,我的问题得到了解决:

state = {
   myObject: {
      inputValue: ''
   }
}

回答by Emperor Krauser

If the props on your component was passed as a state, put a default value for your input tags

如果组件上的 props 作为状态传递,请为输入标签设置默认值

<input type="text" placeholder={object.property} value={object.property ? object.property : ""}>

回答by lakmal_sathyajith

Set a value to 'name' property in initial state.

在初始状态下将值设置为 'name' 属性。

this.state={ name:''};