hichem belfekih
hichem belfekih

Reputation: 115

How to change the state value using a click button

I write a JSX code in order to create a reset button in which i can made a reset to the timer value using "state".The problem is when i click to the button nothing happends instead of getting the value changed.(Even when i want to display a console msg through the reset function nothing happends)

A created a "state.timer" variable in order to add the value of to display. A function to made the reset to the "timer" value and change it to 0. A button which call the reset function in order to made the reset.

import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      timer: 90
    };

    function resetTime() {
      this.setState({ timer: 0 });
    }
  }
  render() {
    return (
      <div className="App">
        <h2>{this.state.timer}</h2>
        <button onClick={this.resetTime}>Reset</button>
      </div>
    );
  }
}

ReactDOM.render(<Timer />, document.getElementById("root"));

Expected to display 0 when i click to the reset button instead the value still display 90.

Upvotes: 2

Views: 51

Answers (3)

kockburn
kockburn

Reputation: 17616

Problem

You had a few things wrong.

  1. You need to use this instead of Timer when accessing setState (ex: this.setState())
  2. You need to wrap the onPress callback in an anonymous function so the context isn't lost (ex: onPress={()=>this.resetTime()} )

Destructuring Assignment:

Writing const {timer} = this.state; is exactly the same as const timer = this.state.timer;

Think of it as a simpler and more elegant way of accessing properties.

Why seperate it ? Well image if you had multiple properties in state (not just timer). That would mean you would have to write this.state.timer, this.state.someOtherProperty, this.state.somethingElse. Why do that and make it harder to read, when you could just do this.

const {timer, someOtherProperty, somethingElse} = this.state;

Code updated:

import React from "react";

export default class Timer extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      timer: 90
    };
  }

  resetTime() {
    this.setState({ timer: 0 });
  }
  render() {
    const { timer } = this.state;
    return (
      <div className="App">
        <h2>{timer}</h2>
        <button onClick={() => this.resetTime()}>Reset</button>
      </div>
    );
  }
}

Working example here.

Upvotes: 3

TRomesh
TRomesh

Reputation: 4481

Try something like this. You will need to bind the function to the constructor.

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      timer: 90
    };
    this.resetTime = this.resetTime.bind(this);
  }

  resetTime() {
    this.setState({ timer: 0 });
  }
  render() {
    return (
      <div className="App">
        <h2>{this.state.timer}</h2>
        <button onClick={this.resetTime}>Reset</button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

You can also you an arrow functions but this technique relies upon the proposed class property feature. To use this approach, you must enable transform-class-properties or enable stage-2 in Babel. If you are using Create-React-App it will be already configured.

 resetTime =()=> {
      this.setState({ timer: 0 });
 }

Upvotes: 1

josepdecid
josepdecid

Reputation: 1847

The state corresponds to the component instance, is not a static variable of your class. Instead of accessing via Timer.setState call it from the instance with this.setState.

Upvotes: 0

Related Questions