user11648045
user11648045

Reputation:

How can i update the counter state each click?

I am working with an API such that on clicking button "show more" there's some counter which increases itself by 25 and display next content:

constructor(props){
this.state = { counter: 0}}
showMore = () => {
axios.get(some_random_link/append/${this.state.counter + 25}/0
  }.then(res => {
  this.setState({ counter: this.state.counter + 25 });
});

render(){
return(
<div>

 <button onClick={this.showMore}>show more</button>

</div>

Expected:

some_random_link/append/25/0
some_random_link/append/50/0
some_random_link/append/75/0

Actual:

some_random_link/append/25/0
some_random_link/append/25/0
some_random_link/append/25/0

Upvotes: 1

Views: 141

Answers (3)

Aziz.G
Aziz.G

Reputation: 3721

this.setState() is asynchronous! so instead of this.setState({}) change it to

this.setState(prev => counter : prev.counter + 25)

For more details check this link: Beware: React setState is asynchronous!

class App extends React.Component {
constructor(props){
super(props)
this.state={counter:0};
}
  showMore = () => {
    axios
      .get(`/fake/fake/fake/${this.state.counter}`)
      .then(() => {
        console.log("fake data");
      })
      .catch(() => {
      console.log(this.state.counter)
        
        this.setState(prevState => ({ counter: prevState.counter + 25 }));
      });
  };
  
  render(){
    return (
       <span style={{background:"green",color:"#fff",padding:"15px",cursor:"pointer"}}onClick={this.showMore}>PLZ CLICK ME</span>
    )
  }
}

ReactDOM.render(<App />, document.querySelector('#root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="root"></div>

Upvotes: 0

Milind Agrawal
Milind Agrawal

Reputation: 2934

setState is an async process, hence when you want to update a state by using the previous one then do it this way

class Counter {
  constructor(props) {
    this.state = { counter: 0 };
  }

  _showMore = () => {
    const { counter } = this.state;
    axios.get(`some_random_link/append/${counter + 25}/0`).then(res => {
      this.setState(prevState => ({ counter: prevState.counter + 25 }));
    });
  };

  render() {
    return (
      <div>
        <button onClick={this._showMore}>show more</button>
      </div>
    );
  }
}

Upvotes: 3

Talgat Saribayev
Talgat Saribayev

Reputation: 1938

Call axios call after setState()

class Counter {
  constructor(props) {
    this.state = { counter: 0 };
  }

  showMore = () => {
    this.setState(
      ({ counter }) => ({ counter: counter + 25 }),
      () => {
        axios.get(`some_random_link/${this.state.counter}/0`); // this.state.counter already updated
      }
    );
  };

  render() {
    return (
      <div>
        <button onClick={this.showMore}>show more</button>
      </div>
    );
  }
}

Upvotes: 0

Related Questions