javascript - 为什么我们不应该直接在 ReactJS 中修改状态?

标签 javascript reactjs

Documentation

例如,这不会重新渲染一个组件:

//错误

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/

相关文章:

javascript - 使用单个数组 Angular c​​omponent.html 显示矩阵

ruby-on-rails - 如何从 Rails api-pagination gem 访问 React 中的响应 header

twitter-bootstrap - 在使用 webpack 进行 React 时导入 bootstrap

javascript - 函数声明与函数表达式

javascript - 为什么 Edge 中的 sessionStorage 与 Firefox/Chrome 不同,我该如何更改?

javascript - 与 lodash 的 promise

javascript - React中如何实现 "normal"ES5原型(prototype)继承?

javascript - 你应该如何在 React.js 中调试 JSX?

javascript - 如何在输入类型日期中设置占位符 [React]

javascript - 如何在 Vue 中切换要加密和未加密的输入字段的内容?