javascript - ReactJS: Why are the constructor called when setState changes the state - Stack Overflow

I'm a newbie to ReactJS and I have made an app where you can submit a name and email. The name and

I'm a newbie to ReactJS and I have made an app where you can submit a name and email. The name and mail should be displayed in a list at the bottom of the page. It is displayed for a short period, but then the constructor gets called and clears the state and the list.

Why is the constructor called after the state change? I thought the constructor only runs once and then the render-method runs after setState() changes the state.

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

I'm a newbie to ReactJS and I have made an app where you can submit a name and email. The name and mail should be displayed in a list at the bottom of the page. It is displayed for a short period, but then the constructor gets called and clears the state and the list.

Why is the constructor called after the state change? I thought the constructor only runs once and then the render-method runs after setState() changes the state.

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

Share Improve this question edited Jan 8, 2018 at 18:58 SSD 1,3912 gold badges13 silver badges20 bronze badges asked Jan 7, 2018 at 19:12 LiraLira 635 bronze badges 2
  • 1 use e.preventDefault() inside onSubmitForm to prevent the form submission, check working codepen – Mayank Shukla Commented Jan 7, 2018 at 19:20
  • probably submit calls a refresh on your page – gmoniava Commented Jan 7, 2018 at 19:41
Add a ment  | 

3 Answers 3

Reset to default 5

The default behavior of a form with input of type submit is to post back to the server.

<input> elements of type "submit" are rendered as buttons. When the click event occurs (typically because the user clicked the button), the user agent attempts to submit the form to the server.

You can pass the event object of the submit handler and use the event.preventDefault method to prevent the form from posting back:

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

Here is a running snippet of your code:

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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app">

</div>

onSubmitForm(e) {
    e.preventDefault(); // prevent the form from refreshing the page 

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

It is working with your codepen link :)

Have a deep look at this :

React - Preventing Form Submission

or

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

Thank you all for your help! :-)

e.preventDefault();

Did fix the problem. Thanks!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745638015a4637513.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信