【问题标题】:How can I ensure a reactjs state is updated, and then call a function?如何确保更新 reactjs 状态,然后调用函数?
【发布时间】:2015-12-08 09:48:11
【问题描述】:

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

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

如何确保我的 this.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

【问题讨论】:

  • 您在此处编写的代码与实际代码有多接近?在更新之前,您没有任何可能更改state.page 的异步调用吗?

标签: reactjs state race-condition


【解决方案1】:

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

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

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

此外,在您的情况下,您可以传递一个函数 do this.setState 而不是做一个可变的舞蹈来增加可读性。

this.setState(function (prevState, currentProps) {
    return {page: prevState.page + 1}
}, this.findByName);

【讨论】:

    【解决方案2】:

    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 这使您有机会在设置新状态并且组件重新呈现自身后运行任何代码

    【讨论】:

      【解决方案3】:

      使用无名函数可以将这段代码写成更短的格式。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-10
        • 2021-05-01
        • 2016-10-02
        • 2019-07-05
        • 1970-01-01
        相关资源
        最近更新 更多