功能组件的setState中的prevState到底是什么?

麦可

返回setState一个从useState钩子获得的(已更改的)先前状态似乎并没有改变状态。运行以下直接代码段

function App(){
  const [state, setState] = React.useState([{x: 0}])
  function changeCount(){
    setState(prevState => {
      console.log('before', prevState[0])
      const newState = [...prevState]
      newState[0].x += 1 //the shallow copy newState could potentially change state
      console.log('after', prevState[0])//here x gets bigger as expected
      return prevState //instead of newState we return the changed prevState
    })
  }
  //checking state shows that x remained 0
  return <div className='square' onClick={changeCount}>{state[0].x}</div>
}
ReactDOM.render(<App/>, document.getElementById('root'))
.square{
  width: 100px;
  height: 100px;
  background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id='root'></div>
通过单击正方形,我们触发 setState 在其中, setState 我们 newState 对先前状态进行了浅表复制 通过更改副本,我们 prevState 在控制台确认时更改了(可能是无意中的)副本 但是,返回更改后的 先前状态 形式 setState 并不会更改状态,因为计数仍为0。如果要返回 newState ,则行为将与预期的一样。

重复这一过程,表明它prevState变大了,似乎不再代表以前的状态了。

这是为什么?我在Codepen上做了这个最小的例子...

塞尔比

考虑对象分配只是一个参考分配,而不是副本

obj1 = {x:42, y:99};
obj2 = obj1;   // obj1 and obj2 both reference the same object
obj1.x += 1;   
obj2.y += 1;
console.log(obj1.x, obj1.y);
console.log(obj2.x, obj2.y);  // prints the same thing since obj1 and obj2 are the same object

在上面的示例中,obj1被初始化为指向具有属性x和y的新对象。创建时obj2=obj1,这不是obj1到obj2的副本,而是obj1和obj2现在引用了同一对象。

因此,在打印console.log语句时,它们将打印相同的内容,因为它们都从同一对象打印属性值。

同样,当从prevState到newState的浅表副本出现时,将对原始对象进行附加引用。

obj = {x:42, y:99};
prevState[0] = obj;     // prevState[0] is a reference to obj.  prevState[0] and obj point to the same exact thing

newState = [...prevState];  // shallow copy, but newState[0] is an object reference.  newState[0] and prevState[0] both point to "obj"

newState[0].x += 1;         // is actually updating the original object assigned to prevState[0]

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章