在反应中设置状态。有没有更好的方法来写这个没有警告错误?

时间:2017-07-21 22:22:31

标签: forms reactjs validation

我正在制作一份有关反应的登记表。我对它的验证部分有点困惑。

截至目前,我在控制台上收到以下警告四次:“警告不要直接改变状态。使用setState()react / no-direct-mutation-state。”

我猜我得到这些错误的原因是因为这些语句“this.state.errors.firstName =”名字必须至少为2个字符。“;”并喜欢这个“this.state.errors = {};”在我的代码中。

但是,我不知道如何做得更好并消除警告。如果你能为我提供一个更好的方法,那将是非常棒的。任何帮助将受到高度赞赏。非常感谢提前!

import React, { Component } from 'react';

import {withRouter} from "react-router-dom";

import HeaderPage from './HeaderPage';

import Logo from './Logo';

import RegistrationForm from './RegistrationForm';

import axios from 'axios';

class Registration extends Component {   

  mixins: [
    Router.Navigation
  ];

  constructor(props) {

    super(props);
    this.state = {
        firstName:'',
        lastName:'',
        email:'',
        errors:{},
        helpText: '',
        helpUrl: '',
        nextLink:''
    };

    this.setUserState = this.setUserState.bind(this);
    this.registrationFormIsValid = this.registrationFormIsValid.bind(this);
    this.saveUser = this.saveUser.bind(this);
  }

  setUserState(e){
    const target = e.target;
    const value = target.value;
    const name = target.name;

    this.setState({[name]: value});
    //delete this line
    console.log(this.state[name]);

  }

  registrationFormIsValid(){

    var formIsValid = true;
    this.state.errors = {};
    //validate first name
    if(this.state.firstName.length < 2){
      this.state.errors.firstName = "First name must be at least 2 characters.";
      formIsValid = false;
    }
    //validate last name
    if(this.state.lastName.length < 2){
      this.state.errors.lastName = "Last name must be at least 2 characters.";
      formIsValid = false;
    }
    //validate email
    if(this.state.email.length < 2){
      this.state.errors.email = "Email must be at least 2 characters.";
      formIsValid = false;
    }

    this.setState({errors : this.state.errors});

    return formIsValid;


  }

  saveUser(e, { history }){
    e.preventDefault();

    // const errorWrappers = document.getElementsByClassName('input'); 

    // for (var i=0; i < errorWrappers.length; i++) {
    // const isError= errorWrappers[i].innerHTML;
    //   if (isError.length > 0){
    //     errorWrappers[i].previousSibling.className = "error-input"
    //   }
    // } 

    if(!this.registrationFormIsValid()){
      return;
    }



    const values = {
      firstName: this.state.firstName,
      lastName: this.state.lastName,
      email: this.state.email,
      password: this.state.password,
      phone: this.state.phone,
      address: this.state.address,
      dob: this.state.birthday
    }

    if (this.props.userRole === 'instructor'){

      axios.post(`/instructors`, values)
      .then((response)=> {
        //delete this line
        console.log(response);
      })
      .catch((error) => {
        console.log(error + 'something went wrooooong');
      });
      this.props.history.push("/success-instructor");

    }else{
       axios.post(`/students`, values)
      .then((response)=> {
        //delete this line
        console.log(response);
      })
      .catch((error) => {
        console.log(error + 'something went wrooooong');
      });

      if (this.props.parent === "false"){
        this.props.history.push("/success-student");
      }else{
        this.props.history.push("/success-parent");
      }
    }

  }
  //end of validation

  render() {
    return (
      <div className="Registration">

        <div className="container menu buttons">
          <HeaderPage/>
        </div>

        <div className="page container narrow">

          <div className="cover-content">

            <Logo/> 

            <div className="container">

              <h2 className="page-title">{this.props.title}</h2>

              <a className="helpLink" href={this.props.helpUrl}>{this.props.helpText}</a>

              <div className="main-content background-white">

               <RegistrationForm
                userRole={this.props.userRole}
                onChange={this.setUserState}
                onSave={this.saveUser}
                errors={this.state.errors}
                  />

                <br/>
                <br/>
                <br/>

              </div>

            </div>

          </div>

        </div>

      </div>
    );
  }
}

export default withRouter(Registration);

2 个答案:

答案 0 :(得分:1)

而不是

this.state.errors = {};

this.state.errors.lastName = "Last name must be at least 2 characters.";

使用

this.setState({errors = {}});
this.setState({ errors: { lastName: "Last name must be at least 2 characters." } });

你需要避免直接改变状态。

警告本身回答了这个问题。请阅读React Doc 小心。

  

“警告不要直接改变状态。使用setState()   反应/无直接突变状态“。

答案 1 :(得分:1)

不要改变state 不要有直接改变状态的代码。相反,创建新对象并进行更改。使用setState完成更改更新状态后。

而不是:

 this.state.errors.someError1="e1";
 this.state.errors.someError2="e2";

这样做:

this.errorsObject=Object.assign({},this.state.errors,{someError1:"e1",someError2:"e2"};

最后:

  this.setState({
  errors:this.errorsObject
  });
  

Object.assign允许我们将一个对象的属性合并到另一个对象的属性中,用匹配的名称替换属性的值。我们可以使用它来复制对象的值而不改变现有的值。