3

I have small class in react, i want to display the result on the screen after i click on the button, but before the display happens, the page reload.

how do i do it?

what am I missing?

import React, {Component} from 'react';

class InputFieldWithButton extends Component{
    constructor(props){
    super();
    this.state = {
      message: ''
    };
  }

  handleChange(e){
    this.setState({
      message: e.target.value
    });
  }

  doSomething(e){
    return(
      <h1>{this.state.message}</h1>
    )
  }

  render(){
    return (
      <div>
        <form >
        <input type="text" placeholder="enter some text!" value=
      {this.state.message}
        onChange={this.handleChange.bind(this)}/>
        <button onClick={this.doSomething.bind(this)}>Click me</button>
          </form>             
      </div>
    )
  }
}

export default InputFieldWithButton;
Malachi Waisman
  • 482
  • 4
  • 14
  • 1
    Possible duplicate of [Stop form refreshing page on submit](https://stackoverflow.com/questions/19454310/stop-form-refreshing-page-on-submit) – HeinousTugboat Dec 14 '17 at 15:55

3 Answers3

4

Your button is inside a form and triggering a submit.
You can use the preventDefault() method to stop it from doing so:

  doSomething(e) {
    e.preventDefault();
    return (
      <h1>{this.state.message}</h1>
    )
  }

By the way, your return statement of this click handler makes no sense at the moment.

Edit
As a followup to your comment:

Can you explain me what is my mistake in the return?

Not really a mistake, but it is useless in this context as your are not doing anything with the returned object.
Where and how do you expect to use the <h1>{this.state.message}</h1> that you are returning?

If you intend to show / hide the input message in your screen you could do it with conditional rendering.
Just store a bool like showMessage in your state and render the message only if it's set to true.

Here is a small example:

class InputFieldWithButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: '',
      showMessage: false
    };
  }

  handleChange = (e) => {
    this.setState({
      message: e.target.value
    });
  }

  toggleMessage = (e) => {
    e.preventDefault();
    this.setState({ showMessage: !this.state.showMessage })
  }

  render() {
    const { showMessage, message } = this.state;
    return (
      <div>
        <form >
          <input
            type="text"
            placeholder="enter some text!"
            value={message}
            onChange={this.handleChange}
          />
          <button onClick={this.toggleMessage}>Toggle Show Message</button>
          {showMessage && <div>{message}</div>}
        </form>
      </div>
    )
  }
}

ReactDOM.render(<InputFieldWithButton />, document.getElementById('root'));
<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="root"></div>

By the way, it is considered as bad practice to bind the functions inside the render method, because you are creating a new instance of a function on each render call. instead do it inside the constructor which will run only once:

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  } 

Or you can use arrow functions which will reference this in a lexical context:

  handleChange = (e) => {
    this.setState({
      message: e.target.value
    });
  }

This is what i've used in my example.

Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
  • Can you explain me what is my mistake in the return? – Malachi Waisman Dec 14 '17 at 20:23
  • Not a mistake, but it is useless as your are not doing anything with the returned object. where and how do you expect to use the `

    {this.state.message}

    ` that you are returning?
    – Sagiv b.g Dec 14 '17 at 20:34
  • I am passing the function as a callback and this method did not stop the auto-reload on button click - `` – Vini Sep 07 '19 at 10:01
2

you're not specifying the buttons'type

<button type="button">
Carluis
  • 23
  • 1
  • 4
2

Set the type attribute on the button to be button. The default is submit since it is wrapped in a form. So your new button html should look like this:

<button type="button" onClick={this.doSomething.bind(this)}>Click me</button>
David Carek
  • 1,103
  • 1
  • 12
  • 26