在过去的几天里,我一直在学习React,研究一些有关编写不同元素的不同方式的教程和说明。但是,我最想知道的是- setState更新/覆盖state组件属性的功能。
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> } } }
这个例子让我从API获取图像。
鉴于我已经执行了此函数的获取,映射和返回操作-然后,我将pictures: []使用在API调用中获得的结果来更新状态数组。
pictures: []
我的问题源于我所见过的关于如何更新/覆盖图片状态属性的不同方法。
我看到它以两种不同的方式编写:
1) 这似乎是一种非常简单易读的方法
this.setState({pictures: pics})
2) 这比较复杂,但我认为它被描述为更安全的方法
this.setState(prevState => ({ pictures: prevState.pictures.concat(pics) }))
有人可以解释使用这两种方法的优点吗?我希望将来与代码保持一致,处理道具和状态等,因此,最通用的方法当然是首选。
首先,在您的情况下,两种语法完全不同,您可能要寻找的是两者之间的区别
this.setState({pictures: this.state.picture.concat(pics)})
和
要了解为什么第二种方法是首选方法,您需要了解React在内部使用setState做什么。
React将首先将您传递给的对象合并setState()到当前状态。然后,它将启动该和解事务。由于调用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文档
如果您尝试在同一周期内多次增加项目数量,则将导致以下结果: Object.assign( previousState, {quantity: state.quantity + 1}, {quantity: state.quantity + 1}, ... ) 后续呼叫将覆盖同一周期中先前呼叫的值,因此数量只会增加一次。如果下一个状态取决于上一个状态,我们建议使用updater函数形式,而不是
如果您尝试在同一周期内多次增加项目数量,则将导致以下结果:
Object.assign( previousState, {quantity: state.quantity + 1}, {quantity: state.quantity + 1}, ... )
后续呼叫将覆盖同一周期中先前呼叫的值,因此数量只会增加一次。如果下一个状态取决于上一个状态,我们建议使用updater函数形式,而不是
因此,如果任何对象包含相同的键,则存储具有相同键的最后一个对象的键的值。因此,更新仅使用最后一个值发生一次