Проблема с формой в React: от контролируемого до неконтролируемого

У меня есть ФОРМА, которая просто должна сохранять значения в состоянии при отправке. Я столкнулся с проблемой при этом,

  1. Я получаю только значение последнего ввода в моем элементе управления формой, то есть:

    formControls: qualification: "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;

Может ли кто-нибудь помочь мне понять, что я делаю не так?


person Adarsh    schedule 16.02.2019    source источник


Ответы (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 переводит ввод в неконтролируемый режим.

person lemieuxster    schedule 16.02.2019
comment
Это неправда. setState отменяет только указанные вами значения, оставляя остальные без изменений. - person Dor Shinar; 16.02.2019
comment
Если в новой версии React это не решено, рекурсивное слияние не выполняется stackoverflow.com/questions/18933985/ - person lemieuxster; 16.02.2019
comment
Ой, извините, я понял, я пропустил тот факт, что он переопределяет formControls внутри состояния. В этом случае вы правы. - person Dor Shinar; 16.02.2019
comment
Хорошо, понял проблему .. это работает нормально. Спасибо большое за вашу помощь. - person Adarsh; 16.02.2019