【问题标题】:Form issue in React: Controlled to uncontrolledReact 中的表单问题:受控到不受控
【发布时间】:2019-07-10 06:28:05
【问题描述】:

我有一个表格,它只需要在提交时将值存储在状态中。 我这样做时遇到了问题,

  1. 我只在我的表单控件中获得最后一个输入的值,即:

    formControls:限定:“a”

  2. 我收到此错误:警告:组件正在将文本类型的受控输入更改为不受控制。 输入元素不应从受控切换到不受控(反之亦然)。决定在组件的生命周期内使用受控输入元素还是不受控输入元素。

我理解了上述问题所以我在构造函数中声明了我的状态,所以我的输入元素甚至在 onChange 函数被触发之前就具有该值。 但这似乎也不能解决我的问题。

下面是我的代码:

import React, { Component } from 'react';
import  './user.css';

class User extends Component {
    constructor(props){
        super(props);
            this.state = {
                formControls: {
                 name: "",
                 age: "",
                 occupation:"",
                 hometown: "",
                 qualification: ""
                } 
             }   
        }


    detailsHandler = (e) => {
       const name = e.target.name;
       const value = e.target.value;
       console.log(name, value)
       this.setState({
        formControls: {
          [name]: value
        }
    });
    }
    submitFormHandler    = (e) => {
        e.preventDefault();
        console.log(this.state)

    }
  render() {
    return (
      <div>
         <div className="main-container">
            <div className="form-header">
                <p className="">Fill details here</p>
            </div>
            <div className="form-container">
            <form onSubmit={this.submitFormHandler}>
            <div className="form-row">
                <div className="form-label"><label>Name: </label></div>
                <input type="text" placeholder="name" name="name" value={this.state.formControls.name} onChange={this.detailsHandler}/>
            </div>
            <div className="form-row">
            <div className="form-label"><label>Age: </label></div>

                <input type="text" placeholder="age"  name="age" value={this.state.formControls.age}  onChange={this.detailsHandler}/>
            </div>
            <div className="form-row">
            <div className="form-label"><label>Occupation: </label></div>

                <input type="text" placeholder="Occupation"  name="occupation" value={this.state.formControls.occupation}  onChange={this.detailsHandler}/>
            </div>
            <div className="form-row">
            <div className="form-label"><label>Hometown: </label></div>
                <input type="text" placeholder="Hometown"  name= "hometown" value={this.state.formControls.hometown}  onChange={this.detailsHandler}/>
            </div>
            <div className="form-row">
            <div className="form-label"><label>Qualification: </label></div>
                <input type="text" placeholder="Qualification" name="qualification" value={this.state.formControls.qualification}  onChange={this.detailsHandler}/>
            </div> 
            <div>

               <input type="submit" value="SUBMIT" />
            </div>
            </form>
            </div>
        </div>
      </div>
    );
  }
}

export default User;

谁能帮我弄清楚我做错了什么?

【问题讨论】:

    标签: javascript reactjs react-redux-form


    【解决方案1】:

    我认为问题在于您如何设置状态。据我所知,状态更新是浅合并(https://reactjs.org/docs/state-and-lifecycle.html#state-updates-are-merged),这意味着当您更新状态时,您正在擦除其他表单控件的值。

    this.setState({
        formControls: {
          [name]: value  // the other values will be lost except for [name]
        }
    });
    

    您需要合并当前状态的表单控件值,或者在状态更新调用中手动包含所有值。

    const oldFormControls = this.state.formControls;
    const newFormControls = Object.assign(oldFormControls,  {
        [name]: value
    });
    
    this.setState({
       formControls: newFormControls
    });
    

    类似的东西。

    编辑:当表单值丢失(null)时,React 会将输入置于不受控制的模式。

    【讨论】:

    • 这不是真的。 setState 仅覆盖您指定的值,而其他值保持不变。
    • 除非更新版本的 React 解决了这个问题,否则它不会进行递归合并 stackoverflow.com/questions/18933985/…
    • 哦,抱歉,我错过了他在州内覆盖 formControls 的事实。在这种情况下你是对的。
    • 好的理解这个问题..这工作正常。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2020-11-28
    • 2020-03-30
    • 1970-01-01
    • 2020-07-08
    • 2019-02-11
    相关资源
    最近更新 更多