何时使用React setState回调

Sah*_*ain 163 callback setstate reactjs

当react组件状态发生变化时,将调用render方法.因此,对于任何状态更改,可以在呈现方法主体中执行操作.那么setState回调是否有特定的用例?

Shu*_*tri 199

是的,因为setStateasynchronous某种程度上工作.打完电话后这意味着setStatethis.state变量不会立即改变.因此,如果要在状态变量上设置状态后立即执行操作然后返回结果,则回调将非常有用

考虑下面的例子

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value });
  this.validateTitle();
},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....
Run Code Online (Sandbox Code Playgroud)

上面的代码可能无法按预期工作,因为title变量在对其执行验证之前可能没有变异.现在您可能想知道我们可以在render()函数本身中执行验证,但如果我们可以在changeTitle函数本身处理它,那将会更好更清洁,因为这会使您的代码更有条理和易懂

在这种情况下,回调很有用

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value }, function() {
    this.validateTitle();
  });

},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....
Run Code Online (Sandbox Code Playgroud)

另一个例子是当你想要dispatch和状态改变时的行动.你会想要在回调中而不是render()每次重新渲染时都会调用它,因此很多这样的场景都可能需要回调.

另一个案例是 API Call

当您需要根据特定的状态更改进行API调用时,可能会出现这种情况,如果您在render方法中执行此操作,则会在每次渲染onState更改时调用它,或者因为某些Prop传递给Child Component更改的.

在这种情况下,您可能希望使用a setState callback将更新的状态值传递给API调用

....
changeTitle: function (event) {
  this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
  // Call API with the updated value
}
....
Run Code Online (Sandbox Code Playgroud)

  • 我了解它本质上是异步的。我的问题是,有什么特定的东西只能用于setState回调,这可能是渲染方法主体可能不支持的(除了可以说更好的代码可读性。) (3认同)
  • 第一个用例可能不是一个好主意。setState回调在重新渲染后触发,因此您没有充分理由导致两次渲染。这正是函数参数(更新程序)的目的。您可以只运行`setState(state => state.title.length?{titleError:“标题不能为空”}:null)`,更改将堆叠。无需双重渲染。 (2认同)

web*_*deb 40

我想到的1. apiusecase 是一个调用,它不应该进入渲染,因为它将运行each状态变化.API调用应仅在特殊状态更改时执行,而不是在每个渲染上执行.

changeSearchParams = (params) => {
  this.setState({ params }, this.performSearch)
} 

performSearch = () => {
  API.search(this.state.params, (result) => {
    this.setState({ result })
  });
}
Run Code Online (Sandbox Code Playgroud)

因此,对于任何状态更改,可以在呈现方法主体中执行操作.

非常糟糕的做法,因为render-method应该是纯粹的,它意味着不应该执行任何动作,状态更改,api调用,只需合成视图并将其返回.应仅对某些事件执行操作.渲染不是一个事件,而是componentDidMount例如.


Ara*_*yev 39

this.setState({
    name:'value' 
},() => {
    console.log(this.state.name);
});
Run Code Online (Sandbox Code Playgroud)

  • 感谢您提供此代码段,该代码段可能会提供一些有限的即时帮助.[正确的解释将大大改善其长期价值](// meta.stackexchange.com/q/114762/206345)通过显示_why_这是一个很好的解决方案,并将使其对未来的读者更有用其他类似的问题.请[编辑]你的答案,添加一些解释,包括你所做的假设. (12认同)
  • 不适用于反应钩子 useState (4认同)
  • 这是非常有帮助的 (2认同)

Ani*_*Jha 23

setState是一个异步函数

所以你不能非常依赖它.例如,让我们考虑在时间t = 0. 应用程序中的不同点在您的应用程序中调用了两个setState函数.在t = 0之前,他们指的是相同的状态.作为同时烧制它们将修改该状态only.Suppose它们中的一个在t = 3这样修改的状态完成执行并创建一个新的状态(称之为因为它STATE_1).现在第二的setState在t = 4.It完成改性在初始状态和创建新状态(将其称为state_2).这个新状态(state_2)与state_1不同.因此我们可以产生数据差异.

因此,每当您的新状态依赖于先前的状态使用状态回调方法.prevState总是指在内存中最后修改的结果的状态.因此,利用prevState的回调函数永远不会导致数据的差异.

错误的代码:

this.setState({ counter: this.state.counter + 1 })
Run Code Online (Sandbox Code Playgroud)

使用具有回调函数的setState更正代码:

this.setState(
   {counter:this.state.counter+1}
 );
Run Code Online (Sandbox Code Playgroud)

通常,回调用于在发生某些事情时运行某些代码.因此,当setState调用成功时更新状态.