如何确保更新reactjs状态,然后调用函数?

时间:2015-09-11 18:40:17

标签: reactjs state race-condition

我正在尝试使用reactjs来更新状态,并且一旦更新,就会触发请求新页面的ajax调用。就在ajax调用触发之前,设置了一个偏移量变量:var offset = this.state.npp * this.state.page;但是我发现clickNextPage()被触发后,this.state.page的值不会更新。

我从根本上不明白这里发生了什么,这似乎是竞争条件,因为我用{this.state.page}观察我的render()函数的状态变化。

如何确保更新my.state.page,然后触发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控制台:

clicked happend
0
1
0

3 个答案:

答案 0 :(得分:13)

setState是异步的,因为this.state不会立即更新。对你的窘境的简短回答是使用在更新内部状态后调用的回调(setState的第二个参数)。例如

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

更长的答案是,在您致电setState后,会调用三个函数(有关每个https://facebook.github.io/react/docs/component-specs.html的详情,请参阅此处):

  • shouldComponentUpdate这允许您检查上一个和新状态,以确定组件是否应自行更新。如果您返回false,则以下函数执行(尽管this.state仍将在您的组件中更新)
  • componentWillUpdate这使您有机会在内部设置新状态并进行渲染之前运行任何代码
  • render这发生在组件“will”和“did”函数之间。
  • componentDidUpdate这使您有机会在设置新状态并且组件重新自我渲染后运行任何代码

答案 1 :(得分:2)

当调用this.setState时,未直接设置新状态,React将其置于挂起状态,通过调用this.state可以返回旧状态。

这是因为React可能批量处理您的状态更新,因此无法保证this.setState是同步的。

您想要做的是this.findByName()componentDidUpdate内的componentWillUpdatethis.setState作为this.setState的第二个参数提供的回调,具体取决于您的使用案例。请注意,在您的调用通过并且组件已重新呈现之后,才会触发对this.setState的回调。

此外,在您的情况下,您可以传递函数this.setState(function (prevState, currentProps) { return {page: prevState.page + 1} }, this.findByName); ,而不是进行变量跳舞以提高可读性。

6

答案 2 :(得分:0)

使用无名功能,此代码可以较短的格式编写。

myReactClassFunction = (param) => {
  this.setState({
    key: value,
  },
  () => this.myClassFunction());
}