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

标签 javascript reactjs state react-hooks react-state-management

在从 useState Hook 获取的 setState 中返回(已更改的)先前状态似乎不会改变状态。运行以下直接代码片段

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>
通过点击方 block 我们触发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]

关于javascript - 功能组件的 setState 中的 prevState 到底是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60107517/

相关文章:

javascript - 在 JavaScript 中,为什么 typeof Function.prototype 是 "function",而不是像其他原型(prototype)对象那样 "object"?

javascript - 去除标签的JS函数

javascript - 箭头函数不应该返回赋值吗?

javascript - react : Pass value of HTML element to event handler onClick

javascript - jQuery mousedown 事件不会在 IE8 中为窗口触发

javascript - 单击按钮 Javascript 后仅显示图像

reactjs - 从 React 前端获取 Azure AD 的访问 token

reactjs - React 传单 map 位置不在 App.js 中时出现故障

javascript - 返回时有错误(我不明白为什么

c# - Unity3D第三方C#库包含