当反应组件状态改变时,将调用render方法。因此,对于任何状态更改,都可以在渲染方法主体中执行操作。那么setState回调是否有特定的用例?
render()
改用此函数 ,则它将在每次更新ANY状态时运行,这可能不是您想要的。这也将使代码的可读性和逻辑性降低。
当反应组件状态改变时,将调用render方法。因此,对于任何状态更改,都可以在渲染方法主体中执行操作。那么setState回调是否有特定的用例?
render()
改用此函数 ,则它将在每次更新ANY状态时运行,这可能不是您想要的。这也将使代码的可读性和逻辑性降低。
Answers:
是的,因为它setState
在asynchronous
某种程度上起作用。打完电话后这意味着setState
该this.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" });
}
},
....
上面的代码可能无法按预期方式工作,因为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" });
}
},
....
另一个示例将是您要dispatch
在状态更改时采取行动。您将希望在回调中执行此操作,而不是在render()
每次进行重新渲染时都会调用它,因此您可能需要回调的情况很多。
另一种情况是 API Call
当您需要基于特定的状态更改进行API调用时,可能会出现这种情况,如果您在render方法中执行此操作,则将在每次渲染onState
更改时调用该API,或者因为某些Prop传递给该Child Component
更改而被调用。
在这种情况下,您可能需要使用setState callback
将更新后的状态值传递给API调用
....
changeTitle: function (event) {
this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
// Call API with the updated value
}
....
if (this.title.length === 0) {
应该是this.state.title.length
吧?
setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)
,更改将堆叠。无需双重渲染。
this.setState({
name:'value'
},() => {
console.log(this.state.name);
});
我想到的1.用例是一个api
调用,不应进入渲染,因为它将运行以进行each
状态更改。而且,API调用仅应在特殊的状态更改上执行,而不应在每个渲染上执行。
changeSearchParams = (params) => {
this.setState({ params }, this.performSearch)
}
performSearch = () => {
API.search(this.state.params, (result) => {
this.setState({ result })
});
}
因此,对于任何状态更改,都可以在渲染方法主体中执行操作。
非常糟糕的做法,因为render
-method应该是纯净的,这意味着不应执行任何操作,状态更改,api调用,只需合并视图并返回即可。仅应在某些事件上执行操作。渲染不是事件,而是componentDidMount
例如。
考虑setState调用
this.setState({ counter: this.state.counter + 1 })
理念
setState可以在异步函数中调用
所以你不能依靠this
。如果上述调用是在异步函数内部进行的,this
则将在该时间点引用组件的状态,但我们希望这是在setState调用或异步任务开始时引用状态内部的属性。并且由于任务是异步调用,因此该属性可能已及时更改。因此,使用this
关键字来引用状态的某些属性是不可靠的,因此我们使用回调函数,其参数为previousState和props,这意味着当异步任务完成并且是时候使用setState进行状态更新时,setv调用时prevState现在将在setState时引用状态尚未开始。确保nextState不会被破坏的可靠性。
错误的代码:将导致数据损坏
this.setState(
{counter:this.state.counter+1}
);
setState具有回调功能的正确代码:
this.setState(
(prevState,props)=>{
return {counter:prevState.counter+1};
}
);
因此,每当我们需要立即基于属性所具有的值将当前状态更新为下一个状态并且所有这些都以异步方式发生时,最好将setState用作回调函数。
我试图在Codepen中解释它 CODE PEN