反应:重构多个表单输入

时间:2018-11-26 18:11:06

标签: javascript reactjs jsx

我正在学习React。我正在进行以下屈光练习之一:

    import React, { Component } from "react";

    import "./App.css";

    class App extends Component {
      state = {
        form: {
          firstName: "",
          lastName: "",
          email: "",
          password: ""
        }
      };

      handleFirstNameChange = e => {
        this.setState({
          form: {
            firstName: e.target.value
          }
        });
      };

      handleLastNameChange = e => {
        this.setState({
          form: {
            lastName: e.target.value
          }
        });
      };

      handleEmailChange = e => {
        this.setState({
          form: {
            email: e.target.value
          }
        });
      };

      handlePasswordChange = e => {
        this.setState({
          form: {
            password: e.target.value
          }
        });
      };

      validateForm = () => {
        const formInputs = ["firstName", "lastName", "email", "password"];

        for (let i = 0; i < formInputs.length; i++) {
          const inputName = formInputs[i];

          if (!this.state.form[inputName].length) {
            return false;
          }
        }

        return true;
      };

      handleSubmit = () => {
        if (this.validateForm()) {
          console.log("Success!");
        } else {
          console.log("Failure!");
        }
      };

      render() {
        return (
          <div
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center"
            }}
          >
            <form
              className="Form"
              onSubmit={e => {
                e.preventDefault();
                this.handleSubmit();
              }}
            >
              <input name="firstName" onChange={this.handleFirstNameChange} />
              <input name="lastName" onChange={this.handleLastNameChange} />
              <input name="email" onChange={this.handleEmailChange} />
              <input name="password" onChange={this.handlePasswordChange} />
              <button className="no-padding">Submit</button>
            </form>
          </div>
        );
      }
    }

    export default App;

我将其重构为:

  import React, { Component } from "react";

  import "./App.css";

  class App extends Component {
    state = {
      form: {
        firstName: "",
        lastName: "",
        email: "",
        password: ""
      }
    };

    handleChange = e => {
      this.setState({
        form: {
          [e.target.name]: e.target.value
        }
      });
    };

    validateForm = () => {
      const formInputs = ["firstName", "lastName", "email", "password"];

      for (let i = 0; i < formInputs.length; i++) {
        const inputName = formInputs[i];

        if (!this.state.form[inputName].length) {
          return false;
        }
      }

      return true;
    };

    handleSubmit = () => {
      if (this.validateForm()) {
        console.log("Success!");
      } else {
        console.log("Failure!");
      }
    };

    render() {
      return (
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            alignItems: "center"
          }}
        >
          <form
            className="Form"
            onSubmit={e => {
              e.preventDefault();
              this.handleSubmit();
            }}
          >
            <input name="firstName" onChange={this.handleChange} />
            <input name="lastName" onChange={this.handleChange} />
            <input name="email" onChange={this.handleChange} />
            <input name="password" onChange={this.handleChange} />
            <button className="no-padding">Submit</button>
          </form>
        </div>
      );
    }
  }

  export default App;

由于某种原因,提交表单时出现错误-

  

TypeError:无法读取未定义的属性“ length”

我想知道我在代码中做错了什么?

还有更好的方法来重构代码吗?

2 个答案:

答案 0 :(得分:4)

这是因为您以错误的方式更新状态,因此在每次更新过程中,每次从表单数组中删除所有其他键值对,而不仅仅是更新任何一个键值。

像这样更新它:

handleChange = e => {
  const { name, value } = e.target;
  this.setState(prevState => ({
    form: {

      // all other key value pairs of form object
      ...prevState.form,

      // update this one specifically
      [name]: value
    }
  }));
};

请查看以下代码片段以获得更好的主意:

let obj1 = { a:1, b:2 };
let obj2 = { a:1, b:2 };

let temp = 'a';

obj1 = { [temp]: 10 };

obj2 = { ...obj2, [temp]: 10 };

console.log('obj1', obj1);
console.log('obj2', obj2);

答案 1 :(得分:1)

这是工作代码段。有两个错误,一个是在handleChange事件中将状态设置为正确的值。电子邮件地址状态属性名称在两个地方不同

https://codesandbox.io/s/5kz5wko31k