reactjs - react 表单错误,将文本类型的受控输入更改为不受控

标签 reactjs

我正在使用受控输入创建一个带有反应的简单表单。在我的组件状态中,我的状态有 2 个属性“clientName”和“license”。改变这些效果很好。但有一个“运输”属性是一个对象。更改任何运输属性都会出错。例如,如果我更改“address1”,一旦在handleShippingChange函数中设置状态,我就会收到错误:

Warning: TextField is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

我怀疑这与我如何定义这些文本字段的值以及如何设置运输属性的状态有关。我究竟做错了什么?我的组件的代码如下:

import React, {Component} from 'react';
    import TextField from 'material-ui/TextField';
    import RaisedButton from 'material-ui/RaisedButton';
    import 'whatwg-fetch';

    class Clients extends Component {
      constructor() {
        super();
        this.state = {
          "clientName": "client name",
          "shipping": {
            "name": "name",
            "address1": "address 1",
            "address2": "address 2",
            "city": "city",
            "state": "state",
            "zip": "zip",
            "country": "country"
          },
          "license": "license"
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleShippingChange = this.handleShippingChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      };       

      handleChange(event) {
        this.setState({
          [event.target.name]: this.getFieldValue(event.target)
        });
      };

      handleShippingChange(event) {
        this.setState({
          shipping: {
            [event.target.name]: this.getFieldValue(event.target)
          }
        });
      };

      getFieldValue(target) {
        return target.type === 'checkbox' ? target.checked : target.value;
      };

      handleSubmit = (event) => {
        event.preventDefault();

        // do some stuff
      };   

      render() {
        return <div>
          <h1>
            Clients Page
          </h1>

          <form onSubmit={this.handleSubmit}>
            <TextField
              hintText="Enter the client name"
              floatingLabelText="Client Name"
              value={this.state.clientName}
              onChange={this.handleChange}
              name="clientName"
            />
            <h2>Shipping Info</h2>
            <TextField
              hintText=""
              floatingLabelText="Name"
              value={this.state.shipping.name}
              onChange={this.handleShippingChange}
              name="name"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="Address Line 1"
              value={this.state.shipping.address1}
              onChange={this.handleShippingChange}
              name="address1"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="Address Line 2"
              value={this.state.shipping.address2}
              onChange={this.handleShippingChange}
              name="address2"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="City"
              value={this.state.shipping.city}
              onChange={this.handleShippingChange}
              name="city"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="State"
              value={this.state.shipping.state}
              onChange={this.handleShippingChange}
              name="state"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="Zip Code"
              value={this.state.shipping.zip}
              onChange={this.handleShippingChange}
              name="zip"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="Country"
              value={this.state.shipping.country}
              onChange={this.handleShippingChange}
              name="country"
            />
            <br />
            <TextField
              hintText=""
              floatingLabelText="License"
              value={this.state.license}
              onChange={this.handleChange}
              name="license"
            />
            <br />
            <RaisedButton label="OK" primary={true} type="submit" />
          </form>
        </div>
      };
    }

    export default Clients;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

最佳答案

受控/不受控输入意味着如果 <input>字段有值或没有值。

// This is a controlled input
<input value="foo"/>

// This is an uncontrolled input
<input value={null}/>

这个想法是您不想从受控输入更改为不受控输入。两种类型的输入行为不同,这可能会导致错误和/或不一致。

最简单的解决方法是确保始终有一个默认值(在空字段的情况下,默认值将为空字符串 '' )。

另外,请注意,如果您对某个值的类型有保证,一致类型通常比可空类型更好。这有助于减少空检查带来的开销 ( if (val != null) { /* ...etc */ } )

但是如果您只想一行修复,您也可以在 jsx 中内联提供默认值:

<input value={value || ''}/>

关于reactjs - react 表单错误,将文本类型的受控输入更改为不受控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42606621/

相关文章:

javascript - 无法过滤数组以在 react 应用程序上获取电影

javascript - NavLink 组件不允许网站渲染并显示其中所有元素的奇怪错误

reactjs - 为什么不能给钩子(Hook)的初始值一个空对象?

javascript - Reactjs 客户端和服务器端一起

reactjs - ReactDOM.findDOMNode(this.refs.a) 与 this.refs.a 有什么不同?

javascript - 在 SVG 文件中将文本作为 prop 传递 - React

javascript - redux-thunk 将调度传递给另一个函数?

javascript - 流错误 - 在 EventTarget 中找不到属性 'contains'

javascript - react typescript : Argument of type '{ [x: number]: any; }' is not assignable to parameter of type

javascript - React中无状态组件中如何设置State、多个对象值?