例如,这不会重新渲染一个组件:
//错误
this.state.comment = 'Hello';
相反,使用 setState():
//正确
this.setState({comment: 'Hello'});
但是,为什么没有答案?使用第二个的理由是什么?
最佳答案
当你使用像 React 这样的高级框架时,他们不会费心去解释如此详细的原因,因为它对于一篇简单的文章来说太复杂了。理解为什么需要深入了解 React 以及 vanilla JavaScript 在底层的工作原理。查看源代码是您的一种选择,但当您从表面上看他们的文档时,生活会更轻松。
虚拟DOM:
React 保留页面先前状态的副本。当它决定应该重绘什么和不应该重绘什么时,它将它用作引用点。当您单击一个按钮时,整个页面不需要将整个 DOM 重新绘制为完全相同的值,但 JavaScript 的糟糕之处在于
JavaScript 中的对象不存在值相等
找到虚拟 DOM 和 React 想要重绘的下一个 DOM 之间的差异是不可能的,因为 JavaScript 没有能力辨别
console.log([] === [])
我的例子没有解释手动改变状态的弱点。就是这个。
this.state = {}
this.state.arr = []
const prevArr = this.state.arr
this.state.arr.push(10)
console.log(this.state.arr === prevArr)
具有新值的 [10]
数组被注册为等于 []
因为相等是通过引用完成的,并且向现有元素添加值是仍然等于它以前的状态。这是修复它的方法。您在 React 中也这样做并非巧合
this.state = {}
this.state.arr = []
const prevArr = [...this.state.arr]
prevArr.push(10)
this.state.arr
console.log(this.state.arr === prevArr)
创建数组的新副本会保留所有指向值的指针,但它在硬件内存中是自己独特的实体。现在他们不同了。当 React 遍历其虚拟 DOM 时,它现在能够注册您将 10
插入到您的数组中,并希望它反射(reflect)在 DOM 的下一次迭代中。
this.setState 触发重新渲染
重新渲染并不是 DOM 的完整重绘。当它发现差异时,它会触发对您传入的特定元素的重新绘制。
关于javascript - 为什么我们不应该直接在 ReactJS 中修改状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51181264/