手动改变 React 的状态,然后调用 setState

Posted

技术标签:

【中文标题】手动改变 React 的状态,然后调用 setState【英文标题】:Mutating state on React manually, then calling setState 【发布时间】:2017-11-18 02:39:50 【问题描述】:

我正在研究 React JS 制作一个简单的待办事项列表,我的部分代码如下:

changeStatus(e, index) 
    this.state.tasks[index].status = e.target.value;
    this.setState((prevState) => (
        tasks: prevState.tasks
    ));

正如 React 文档所说,我们不应该手动更改 state,而应该调用 setState,因此,我在控制台上收到警告说,即使在手动更改后调用 setState

我这样做是因为,对我来说,这样做比分离 task、在我的数组上执行 splice 并使用新值调用 setState 更实际。

我的方法有问题吗?您如何建议以高效且非重复的方式更新状态?

【问题讨论】:

The React docs outline why this is a bad idea: "永远不要直接修改 this.state,因为之后调用 setState() 可能会替换你所做的修改"。换句话说,如果您直接改变状态,则无法保证您的更改实际上会持续存在。 因为我来自 Vue,所以这不是我关心的问题。谢谢! 是的,Vue 通常在设计时似乎考虑到了变异(这就是为什么很多人喜欢它而不是 React,即使这不是我个人的偏好)。你必须在 React 中使用 setState 的原因是它允许优化 - 例如如果您连续两次快速调用setState,它们可能会合并为一次执行的批量更新。再次引用文档:“将setState 视为更新组件的请求,而不是立即命令。” 太棒了。我首先采用了 Vue,因为它非常适合我正在开发的一些应用程序。我现在选择学习 React 以将其与 React Native 应用程序一起使用并且由于市场份额,尽管我仍然更喜欢 Vue。 【参考方案1】:

试试这个:

   changeStatus(e, index) 
      const tmp =  ...this.state ;
      tmp.tasks[index].status = e.target.value;
      this.setState(tmp);
   

【讨论】:

简单易懂。【参考方案2】:

您不应该直接改变状态,这样做会从状态创建一个新对象,然后更新它并将其设置回状态

changeStatus(e, index) 
    var tasks = ...this.state.tasks
    tasks[index].status = e.target.value;
    this.setState(tasks);

如果您想知道...this.state.tasks 做了什么,请查看以下答案:

What is the meaning of this syntax "...x" in Reactjs

但是,您也可以使用 ES5 Object.assign() 运算符复制状态

var tasks = Object.assign(, this.state.tasks)

【讨论】:

以上是关于手动改变 React 的状态,然后调用 setState的主要内容,如果未能解决你的问题,请参考以下文章

react学习笔记-06

即使该组件的道具或状态没有改变,也会调用 React shouldComponentUpdate()

React useState() 使用指南

Vue,和React,实现的双向数据绑定效果

只要鼠标悬停在 React 中的元素上,就会改变状态

react脚手架应用