Javascript 何时使用功能设置状态
在过去的几天里,我一直在学习React,看一些教程和关于编写不同元素的不同方法的解释。然而,有一个我一直最感兴趣的功能是Javascript 何时使用功能设置状态,javascript,html,reactjs,Javascript,Html,Reactjs,在过去的几天里,我一直在学习React,看一些教程和关于编写不同元素的不同方法的解释。然而,有一个我一直最感兴趣的功能是setState函数,用于更新/覆盖组件的state属性 例如,假设我有一个具有以下内容的类: class Photos extends React.Component { constructor() { super() state = { pictures: [] } } comp
setState
函数,用于更新/覆盖组件的state
属性
例如,假设我有一个具有以下内容的类:
class Photos extends React.Component {
constructor() {
super()
state = {
pictures: []
}
}
componentDidMount() {
// This is where the fetch and setState will occur (see below)
}
render() {
return {
<div className="container">
{this.state.pictures}
</div>
}
}
}
有人能解释一下这两种方法的优点吗?我希望将来与代码保持一致,处理道具和状态等,因此当然会首选最通用的方法。TL;DR:功能性
setState
主要有助于在短时间间隔内触发多个setState
s时期望正确的状态更新,而传统的setState
会进行对账,并可能导致意外状态
请查看这篇精彩的文章,以获得清晰的理解
这里是
首先,您尝试在每种情况下执行不同的操作,在一种情况下分配图片,在另一种情况下连接图片
假设.state.pictures包含[1,2,3]
,pics包含[4,5,6]
this.setState(prevState => ({
pictures: prevState.pictures.concat(pics)
}))
this.setState({pictures:pics})
在上述情况下,this.state.pictures将包含图片,即this.state.pictures=[4,5,6]
this.setState(prevState => ({
pictures: prevState.pictures.concat(pics)
}))
而在上述代码段中,this.state.pictures将包含以前的图片+图片,即this.state.pictures=[1,2,3,4,5,6]
this.setState(prevState => ({
pictures: prevState.pictures.concat(pics)
}))
无论哪种方式,您都可以调整它以满足您的API需求,如果它像分页响应,则最好将每个请求的结果串联起来,否则如果每次都获得整个数组,则只需分配整个数组即可
常规设置状态与功能设置状态
现在,您的问题可能主要是将setState
用于对象还是函数
人们出于不同的原因使用它们,现在功能性的setState
被称为是安全的,因为React
执行一种称为协调过程的操作,在该过程中,当频繁或同时触发时,将setState
内的多个对象合并,并一次性应用更改,有点像批处理。这可能会在下面这样的场景中导致一些意外的结果
示例:
increaseScoreBy3 () {
this.setState({score : this.state.score + 1});
this.setState({score : this.state.score + 1});
this.setState({score : this.state.score + 1});
}
正如您希望分数增加3一样,React所做的是合并所有对象并只更新分数一次,即增加1
这是函数回调的亮点之一,因为函数上不会发生协调,执行下面的代码将按预期执行操作,即将分数更新3
increaseScoreBy3 () {
this.setState(prevState => ({ score: prevState.score + 1 }));
this.setState(prevState => ({ score: prevState.score + 1 }));
this.setState(prevState => ({ score: prevState.score + 1 }));
}
首先,在你的例子中,这两种语法是完全不同的,你可能要寻找的是它们之间的区别
this.setState({pictures: this.state.picture.concat(pics)})
及
要理解为什么第二种方法是首选方法,您需要了解React在内部如何使用setState()
React将首先将传递给setState()
的对象合并到当前状态。然后就开始和解了。由于调用setState()
可能不会立即更新您的状态
React可以将多个setState()
调用批处理到单个更新中,以获得更好的性能
考虑一个简单的例子,为了理解这一点,您可以在函数中多次调用setState()
,如下所示:
myFunction = () => {
...
this.setState({pictures: this.state.picture.concat(pics1)})
this.setState({pictures: this.state.picture.concat(pics1)})
this.setState({pictures: this.state.picture.concat(pics1)})
...
}
在一个简单的应用程序中,这不是一个有效的用例,但随着应用程序变得复杂,多个setState()
调用可能会从多个地方发生,执行相同的操作
因此,现在要执行有效的更新,React通过提取传递给每个setState()
调用的所有对象来进行批处理,将它们合并在一起形成单个对象,然后使用该单个对象执行setState()
。根据setState()
文档:
这种形式的setState()
也是异步的,同一周期内的多个调用可以批处理在一起。例如,如果您试图在同一周期内增加一个项目数量不止一次,则会产生以下等效结果:
Object.assign(
previousState,
{quantity: state.quantity + 1},
{quantity: state.quantity + 1},
...
)
后续调用将覆盖同一周期中以前调用的值,因此数量只增加一次。如果下一个状态取决于当前状态,我们建议使用updater函数表单,而不是:
this.setState((state) => {
return {quantity: state.quantity + 1};
});
有关详细信息,请参见:
始终使用setState()的函数形式。
this.setState((state, props)=>({
someValue: state.somevalue + 1
}));
这种方法不太容易出错,有助于消除一些很难找到的bug。即使有多个这样的更新,每个更新都是单独的函数调用,后续更新也不会导致某些更新丢失
另一种方法
this.setState({
someValue: state.somevalue + 1
});
如果频繁重复,可能会导致某些更新丢失,因为React会批量处理此类频繁更新 这两段代码不是等价的-第1版将
状态设置为。图片设置为图片,而第2版将状态设置为。图片设置为上一个状态。图片结尾附加图片。@JoeClay,不,它不是,因为它不是回调函数,而是更新函数setState@ShubhamKhatri:哇,是的,你说得对。撤回了我的投票结果。但是,如果我在increaseScoreBy3中只有一个setState调用,this.setState({score:this.state.score+1})
应该按预期工作吗?在这种情况下,使用函数回调不会使