【问题标题】:ReactJS: Why are the constructor called when setState changes the stateReactJS:为什么在setState改变状态时调用构造函数
【发布时间】:2018-06-16 20:42:23
【问题描述】:

我是 ReactJS 的新手,我制作了一个应用程序,您可以在其中提交姓名和电子邮件。姓名和邮件应显示在页面底部的列表中。它会显示一小段时间,然后调用构造函数并清除状态和列表。

为什么在状态改变后调用构造函数?我以为构造函数只运行一次,然后render-方法在setState() 更改状态后运行。

class App extends React.Component {
    constructor(props) {
        super(props);

        console.log("App constructor");

        this.state = {
          signedUpPeople: []
        };

        this.signUp = this.signUp.bind(this);
    }

    signUp(person) {
        this.setState({
          signedUpPeople: this.state.signedUpPeople.concat(person)
        });
    }

    render() {
        return (
          <div>
            <SignUpForm signUp={this.signUp} />
            <SignedUpList list={this.state.signedUpPeople} />
          </div>
        );
    }
}

class SignUpForm extends React.Component {
    constructor(props) {
        super(props);

        console.log("SignUpForm constructor");

        this.state = {
          name: "",
          email: ""
        };

        this.changeValue = this.changeValue.bind(this);
        this.onSubmitForm = this.onSubmitForm.bind(this);
    }

    changeValue(event) {
        const value = event.target.value;
        const name = event.target.name;

        this.setState({
          name: value
        });
    }

    onSubmitForm() {
        this.props.signUp(this.state);
        this.setState({
          name: "",
          email: ""
        });
    }

    render() {
        console.log("SignUpForm render");
        return (
          <div>
            <h2>Sign up</h2>
            <form onSubmit={this.onSubmitForm}>
              <label htmlFor="name">Name:</label>
              <input id="name" name="name" onChange={this.changeValue} />
              <br />
              <label htmlFor="email">E-mail:</label>
              <input id="email" name="name" onChange={this.changeValue} />
              <input type="submit" value="Sign up" />
            </form>
          </div>
        );
    }
}

class SignedUpList extends React.Component {
    render() {
        console.log("SignedUpList render");
        return (
          <div>
            <h2>Already signed up</h2>
            <ul>
              {this.props.list.map(({ name, email }, index) => (
                <li key={index}>
                  {name}, {email}
                </li>
              ))}
            </ul>
          </div>
        );
    }
}

ReactDOM.render(<App />, window.document.getElementById("app"));

See CodePen example

【问题讨论】:

  • onSubmitForm里面使用e.preventDefault()来阻止表单提交,检查working codepen
  • 可能在您的页面上提交调用刷新

标签: javascript reactjs


【解决方案1】:

forminput 类型为提交 is to post back to the server 的默认行为。

&lt;input&gt;“提交”类型的元素呈现为按钮。当。。。的时候 点击事件发生(通常是因为用户点击了按钮), 用户代理尝试将表单提交到服务器。

您可以传递提交处理程序的event 对象并使用event.preventDefault 方法来防止表单回发:

onSubmitForm(e) {
      e.preventDefault();
      this.props.signUp(this.state);
      this.setState({
        name: "",
        email: ""
      });
    }

这是您代码的运行 sn-p:

class App extends React.Component {
    constructor(props) {
      super(props);
  
      console.log("App constructor");
  
      this.state = {
        signedUpPeople: []
      };
  
      this.signUp = this.signUp.bind(this);
    }
  
    signUp(person) {
      this.setState({
        signedUpPeople: this.state.signedUpPeople.concat(person)
      });
    }
  
    render() {
      return (
        <div>
          <SignUpForm signUp={this.signUp} />
          <SignedUpList list={this.state.signedUpPeople} />
        </div>
      );
    }
  }
  
  class SignUpForm extends React.Component {
    constructor(props) {
      super(props);
  
      console.log("SignUpForm constructor");
  
      this.state = {
        name: "",
        email: ""
      };
  
      this.changeValue = this.changeValue.bind(this);
      this.onSubmitForm = this.onSubmitForm.bind(this);
    }
  
    changeValue(event) {
      const value = event.target.value;
      const name = event.target.name;
  
      this.setState({
        name: value
      });
    }
  
    onSubmitForm(e) {
      e.preventDefault();
      this.props.signUp(this.state);
      this.setState({
        name: "",
        email: ""
      });
    }
  
    render() {
      //console.log('SignUpForm render');
      return (
        <div>
          <h2>Sign up</h2>
          <form onSubmit={this.onSubmitForm}>
            <label htmlFor="name">Name:</label>
            <input id="name" name="name" onChange={this.changeValue} />
            <br />
            <label htmlFor="email">E-mail:</label>
            <input id="email" name="name" onChange={this.changeValue} />
            <input type="submit" value="Sign up" />
          </form>
        </div>
      );
    }
  }
  
  class SignedUpList extends React.Component {
    render() {
      //console.log('SignedUpList render');
      return (
        <div>
          <h2>Already signed up</h2>
          <ul>
            {this.props.list.map(({ name, email }, index) => (
              <li key={index}>
                {name}, {email}
              </li>
            ))}
          </ul>
        </div>
      );
    }
  }
  
  ReactDOM.render(<App />, window.document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app">

</div>

【讨论】:

    【解决方案2】:
    onSubmitForm(e) {
        e.preventDefault(); // prevent the form from refreshing the page 
    
        this.props.signUp(this.state);
        this.setState({
          name: "",
          email: ""
        });
    }
    

    它正在使用您的 codepen 链接:)

    深入了解一下:

    React - Preventing Form Submission

    https://medium.com/@ericclemmons/react-event-preventdefault-78c28c950e46

    【讨论】:

      【解决方案3】:

      感谢大家的帮助! :-)

      e.preventDefault();
      

      确实解决了问题。谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-31
        • 1970-01-01
        • 2018-08-17
        • 2019-04-04
        • 2015-08-27
        相关资源
        最近更新 更多