John
John

Reputation: 67

React : How to avoid multiple function call

I am working on small react project, actually I have some problem regarding to function call. I am updating the value of URL and invoke the method through button click to display updated values but whenever I click the button first it give me old values when I click again it give me updated values. Could someone please help me how to avoid old values on first click, I want to show updated values on first click not on second click. I am new to ReactJS , Could someone please help me how to fix this problem?

Full Component Code

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

    this.state = {
      Item: 5,
      skip: 0
    }

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

  urlParams() {
    return `http://localhost:3001/meetups?filter[limit]=${(this.state.Item)}&&filter[skip]=${this.state.skip}`
  }

  handleClick() {
    this.setState({skip: this.state.skip + 1})
  }

  render() {
    return (
      <div>
        <a href={this.urlParams()}>Example link</a>
        <pre>{this.urlParams()}</pre>
        <button onClick={this.handleClick}>Change link</button>
      </div>
    )
  }
}


ReactDOM.render(<Example/>, document.querySelector('div#my-example' ))

Upvotes: 1

Views: 3525

Answers (2)

Jolly
Jolly

Reputation: 1768

There's quite lots of code e no working example, so I may be wrong, but I think the problem is in getSortedData(): in that function, you call setState() and right after you call getData() which will perform a fetch, which uses ulrParams() function, which uses property this.state.sortedData.

The problem in this is that setState() is async, so it's not sure that, when urlParams() uses this.state.sortedData, the property is updated (actually, we are sure it's not updated).

Try to rewrite getSortedData() as follow:

getSortedData =() => {
    this.setState({sortedData:'name desc'}, () => {
        this.getData();
    })
}

What I'm doing here is passing a callback to setState(): doing this way, getData() will be called AFTER you've updated the state.


Regarding the question you asked in the comment, if you want to toggle the order, you can add a property order in the state of the Component, assigning to it a default value 'name desc'.
Then, you change getSortedData as follow:

getSortedData =() => {
    let newSort = 'name asc';
    if (this.state.sorteData === newSort) 'name desc';

    this.setState({sortedData: newSort}, () => {
        this.getData();
    })
}

Upvotes: 1

fahad tufail
fahad tufail

Reputation: 615

State is not updating at time when urlParams is being called. As @jolly told you setState is Asynch function so it's better to use it in a callback or you may simply pass your sortedData type as in argument in getSortedType function instead of updating state. Also, ReactJS community suggests or the best practice is to use state only if props are needed to be updated.

In case, if you dont feel comfortable with CB. you may use setTimeOut which I think is a bad practice but it would solve your problem. your code would be like:

getSortedData=()=>{
    this.setState({sortedData:'name desc'});
    setTimeout(() => {
      this.getData();
    }, 200);
}

Upvotes: 1

Related Questions