【问题标题】:React updating state in two input fields from form submission来自表单提交的两个输入字段中的反应更新状态
【发布时间】:2017-04-23 03:18:55
【问题描述】:

我正在尝试使用 React 制作一个简单的联系表单。最终,我将从状态收集的数据发送到数据库,但目前我正试图将其用于控制​​台记录正确的值。

现在,电子邮件字段覆盖了名称字段,当我在控制台记录这两种状态时,名称显示并且电子邮件未定义。这是我的 React 组件

import React, { Component, PropTypes } from 'react';
import ContactData from '../data/ContactData.js';


class FormContact extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: '',
            email: '',
            textArea: ''
        }
    }

    handleChange(event) {
        event.preventDefault();
        this.setState({
            name: event.target.value,
            email: event.target.email
        })
    }

    handleSubmit(event) {
        event.preventDefault();
        console.log(this.state.name + ' ' + this.state.email);
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit.bind(this)}>
                <label> Name:
                    <input type="text" placeholder="Name" value={this.state.name} onChange={this.handleChange.bind(this)} />
                </label><br />
                <label> Email:
                    <input type="text" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this)}/>
                </label><br />
                    <input className="btn btn-primary" type="submit" value="Submit" />
           </form>
        )
    }
}

FormContact.PropTypes = {
    subName: PropTypes.string,
    subEmail: PropTypes.string
}

FormContact.defaultProps = {
    subName: 'Sam',
    subEmail: ''
}

class Contact extends Component {
    render() {
        return (
            <div>
                <h1>CONTACT PAGE</h1>
                <FormContact />
            </div>
        )
    }
}


export default Contact;

【问题讨论】:

    标签: forms reactjs components state


    【解决方案1】:

    事件元素上不存在对event.target.email 的引用。对于电子邮件和姓名,来自内联事件处理程序的文本输入值将是 event.target.value。快速的解决方案是为每个输入创建一个单独的处理程序:

    handleChangeName(event) { 
      event.preventDefault();
      this.setState({ name: event.target.value });  //<-- both use the same reference
    }                                               //    to get the contextual value
    handleChangeEmail(event) {                      //    from the inputs v
      event.preventDefault();                       //                    |
      this.setState({ email: event.target.value }); //<--------------------
    }

    【讨论】:

    • 是的,我知道两个不同的处理程序可以工作,但我觉得必须有一种方法可以一次处理所有这些,否则更大的表单提交将有大量的处理程序函数。一定有更好的方法(不使用 refs,因为我听说那些不好)
    • 我明白了。在这种情况下,您是否尝试将额外的参数传递给 bind: which 是您要更改的值的字符串名称?然后handleChange 方法可以在 setState 中动态使用该值。另一种选择是创建一个包装输入并有效地使其成为“哑”受控输入的高阶组件。
    【解决方案2】:

    如果我明白你想要什么,你可以这样做:

    • 在您的状态中为表单值添加一个空对象

      formValues: {}

    • 将名称属性添加到您的字段

      &lt;input name="name" .... /&gt; &lt;input name="email" .... /&gt;

    • 然后根据该名称更新您在 handleChange 函数中的状态

      let formValues = this.state.formValues;
      let name = event.target.name; // Field name
      let value = event.target.value; // Field value
      
      formValues[name] = value;
      
      this.setState({formValues})
      
    • 如果值更深一层,您可以使用 value={this.state.formValues["name"]} 而不是 value={this.state.name} - 其中 name 是输入字段的 name 属性的值

    因此,一切都应该如下:

    class Test extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                formValues: {}
            }
        }
    
        handleChange(event) {
            event.preventDefault();
            let formValues = this.state.formValues;
            let name = event.target.name;
            let value = event.target.value;
    
            formValues[name] = value;
    
            this.setState({formValues})
        }
    
        handleSubmit(event) {
            event.preventDefault();
            console.log(this.state.formValues);
        }
    
            render(){
            return (
            <form onSubmit={this.handleSubmit.bind(this)}>
                    <label> Name:
                        <input type="text" name="name" placeholder="Name" value={this.state.formValues["name"]} onChange={this.handleChange.bind(this)} />
                    </label><br />
                    <label> Email:
                        <input type="text" name="email" placeholder="Email" value={this.state.formValues["email"]} onChange={this.handleChange.bind(this)}/>
                    </label><br />
                        <input className="btn btn-primary" type="submit" value="Submit" />
               </form>
          )
        }
    }
    
    React.render(<Test />, document.getElementById('container'));
    

    Here is fiddle.

    希望这会有所帮助。

    【讨论】:

    • 我会在下班后进行设置 - 看起来就像我要找的一样,谢谢!
    • FormContact 正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控切换到受控(反之亦然)。在组件的生命周期内决定使用受控输入元素还是不受控输入元素。 - - 产生这个错误
    • 要修复不受控制的输入问题,您必须使用空字符串来初始化 formValues 对象的名称和电子邮件。
    • @boky 当我点击你的小提琴时,它就坏了。
    • @unflores 已更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2020-12-26
    • 2021-09-08
    • 2021-11-27
    • 2013-11-05
    • 1970-01-01
    • 2021-07-11
    相关资源
    最近更新 更多