Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ensure a reactjs state is updated, and then call a function?

I'm trying to use reactjs to update a state, and once it is updated fire an ajax call requesting a new page. Just before the ajax call fires an offset variable is set: var offset = this.state.npp * this.state.page; However I find after clickNextPage() is fired, the value of this.state.page is not updated.

I fundamentally do not understand what is happening here, this appears to be a race condition, because I watch the state change on my render() function with {this.state.page}.

How can I ensure my this.state.page is updated, and then fire findByName()?

  clickNextPage: function(event){
    console.log("clicked happend")
    page = this.state.page;
    console.log(page)
    page += 1
    console.log(page)
    this.setState({page: page});
    console.log(this.state.page)
    this.findByName()
  },

JS Console:

clicked happend
0
1
0
like image 861
JZ. Avatar asked Sep 11 '15 18:09

JZ.


People also ask

How do you call a function after a state change React?

The first and most commonly used method to run a function after updating state is the useEffect hook. useEffect runs its function only when the items in the dependency array change.

How do you make sure React state is updated?

To update state in React components, we'll use either the this. setState function or the updater function returned by the React. useState() Hook in class and function components, respectively.

How do you update state in functional component React?

React class components have a state property that holds their state. They provide a setState() method you can use to update the state, triggering a re-render. In this example, the rendered text will always show the number in the component's state. Clicking the button will increment the value.


2 Answers

setState is asynchronous in that this.state will not be updated right away. The short answer to your quandary is use the callback (the second parameter to setState) which is invoked after the internal state is been updated. For example

this.setState({page: page}, function stateUpdateComplete() {
    console.log(this.state.page)
    this.findByName();
}.bind(this));

The longer answer is that after you call setState, three functions are called (see here for more details about each https://facebook.github.io/react/docs/component-specs.html):

  • shouldComponentUpdate this allows you to inspect the previous and new state to determine whether the component should update itself. If you return false, the following functions are not executed (although the this.state will still be updated within your component)
  • componentWillUpdate this gives you a chance to run any code before the new state is set internally and rendering happens
  • render this happens between the component "will" and "did" functions.
  • componentDidUpdate this gives you a chance to run any code after the new state is set and the component has re-rendered itself
like image 101
Ed Ballot Avatar answered Oct 16 '22 18:10

Ed Ballot


When calling this.setState the new state isn't set directly, React puts it in a pending state which by calling this.state can return the old state.

This is because React might batch your state updates and therefore offers no guarantee that this.setState is synchronous.

What you want to do is called this.findByName() within componentDidUpdate, componentWillUpdate or through the callback offered as a second argument to this.setState depending on your use case. Note that the callback to this.setState won't be fired until after your call has passed and the component has re-rendered itself.

Furthermore in your case you could pass a function do this.setState instead of doing a variable dance to increase readability.

this.setState(function (prevState, currentProps) {
    return {page: prevState.page + 1}
}, this.findByName);
like image 32
Henrik Andersson Avatar answered Oct 16 '22 17:10

Henrik Andersson