【问题标题】:Why do I need to wrap setState callback in an anonymous arrow function for it to run after state change?为什么我需要将 setState 回调包装在匿名箭头函数中以使其在状态更改后运行?
【发布时间】:2020-09-11 02:12:14
【问题描述】:

我要疯了。我有一个反应类,它有一些这样的方法:

handleSubmit = (e) => {
    this.setState({
        isLoading: true,
    }, this.doSearch());
}

changePage = (e) => {
    this.setState({
        searchPage: e,
        isLoading: true
    }, this.doSearch());
}

当用户在该组件的渲染中点击搜索表单上的提交时,我使用handleSubmit

<button type="button" id="btn-search" onClick={event => this.handleSubmit(event)}>Search</button>

这很好,它提交,设置状态,然后在设置 isLoading: true 后调用 this.doSearch。

获得搜索结果后,我调用一个子组件来显示结果列表,并为它提供一个处理程序,以便用户点击分页:

<ResultList searchResult={searchResult} changePage={this.changePage} />

在孩子内部,只有一个带有 onClick 的简单跨度:

<span onClick={event => props.changePage(props.searchResult.page + 1)}>&gt;&gt;</span>

所以当用户点击下一页... pager 时,处理程序被调用。我可以注销e 并看到数字增加了。然后我调用 setState 并告诉它在状态更新后使用父类的doSearch()。相反,这是我的目标。但它在状态更新之前一直运行doSearch()。但我知道状态在某些时候会完成更新,因为当组件重新渲染时,状态已更新为 searchPage

在状态更新完成后,我似乎能够让它运行我的回调的唯一方法是将它包装在一个箭头函数中,使其看起来像这样:

changePage = (e) => {
    this.setState({
        searchPage: e,
        isLoading: true
    }, () => {
        this.doSearch()
    });
}

这只是changePage 的问题,它被传递给子组件,然后从那里调用,目的是增加或减少searchPage。从提交处理程序调用this.doSearch() 很好。

我觉得我不了解范围界定或 this.state 或实例或其他东西......

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    让你感到困惑的是 JavaScript 中的求值顺序,它与 React 无关。

    如果你有

    foo(this.doSearch())
    

    doSearch 将被立即调用。也就是说,即使 before foo 被调用,然后doSearchresult 也会被传递给foo

    您不希望这样,您想将 计算 传递给 setState 函数。也就是说,你要传递函数 doSearch,而不是函数的结果。

    所以你真正想要的是

    changePage = (e) => {
        this.setState({
            searchPage: e,
            isLoading: true
        }, this.doSearch);
    }
    

    这意味着您将 函数 this.doSearch 传递给 setState。当然,this.doSearch 等价于() =&gt; this.doSearch()(两者都是函数,调用时调用this.doSearch())。

    【讨论】:

    • 啊...我不应该有 ()ed 它。但由于某种原因handleSubmit 似乎可以工作,但也许它足够快,加载消息似乎并没有真正受到影响。那是我生命中的几个小时,我不会回来。非常感谢。
    【解决方案2】:

    立即调用它并将其返回值作为要使用的回调传递(错误)。另一个创建一个函数,那个被用作回调(好)。

    就像不小心写了一个这样的事件监听器:

    // Assign console.log as the callbak
    // Will print the event argument on click
    // (just mentioning for completeness)
    addEventlistener("click", console.log)
    
    // vs
    
    // Immediately print "a"
    // Add undefined as callback
    // (your first example [bad])
    addEventlistener("click", console.log("a")):
    
    // vs
    
    // Add function that will print "a" after a click
    // (your second example [good])
    addEventlistener("click", () => console.log("a"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2018-08-05
      相关资源
      最近更新 更多