setState():不要直接改变状态。使用 setState()

Posted

技术标签:

【中文标题】setState():不要直接改变状态。使用 setState()【英文标题】:setState(): Do not mutate state directly. Use setState() 【发布时间】:2019-07-10 12:31:22 【问题描述】:

我在运行代码时收到以下警告:

第 48 行:不要直接改变状态。使用 setState() 反应/无直接突变状态

此警告涉及以下代码行:

updateDelay(prediction_arr,prediction_dep) 
  this.state.chartDataWake = [...this.state.chartDataWake, wake: this.state.wake===84.73 ? "H" : (this.state.wake===14.78 ? "M" : "L"), delay: prediction_arr];
  this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, turnaround: this.state.schedTurnd, delay: prediction_arr];

  this.setState(
    prediction_arr: prediction_arr,
    prediction_dep: prediction_dep,
    delay_arr_cat: prediction_arr===0 ? "<15" : (prediction_arr===1 ? "[15; 45]" : ">45")
  );
;

我知道我应该将所有声明放在this.setState( 中。但是我不清楚我应该如何改变

this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, turnaround: this.state.schedTurnd, delay: prediction_arr];

为了能够编译代码。

【问题讨论】:

【参考方案1】:

永远不要使用this.state.YOUR_VARIABLE = something修改状态

如果你愿意,并且从你所做的 sn-p 中看到, 要将 prevState 复制到您的新状态并能够向其添加新元素,您应该使用对象克隆首先复制先前的状态,然后在此副本中添加您想要的更多元素。

updateDelay(prediction_arr, prediction_dep) 
 const newChartDataWake = [...this.state.chartDataWake, 
  wake: this.state.wake === 84.73 ? "H" : (this.state.wake === 14.78 ? "M" : "L"),
  delay: prediction_arr
 ];

 const newChartDataTurnaround = [...prevState.chartDataTurnaround, 
  turnaround: prevState.schedTurnd,
  delay: prediction_arr
 ]



 this.setState(prevState => 
  return 
   chartDataWake: newChartDataWake
   chartDataTurnaround: newChartDataTurnaround
   prediction_arr: prediction_arr,
   prediction_dep: prediction_dep,
   delay_arr_cat: prediction_arr === 0 ? "<15" : (prediction_arr === 1 ? "[15; 45]" : ">45")
  
 );
;

【讨论】:

【参考方案2】:

1- 不要直接使用 setState 改变状态,所以删除前两行。

2- 因为setState is async 并且您正在根据之前的值更新状态,所以使用updater function,意味着在setState 中传递一个函数并在该函数中使用prevState 值。

像这样:

updateDelay(prediction_arr,prediction_dep) 
  this.setState(prevState => (
    prediction_arr: prediction_arr,
    prediction_dep: prediction_dep,
    delay_arr_cat: prediction_arr===0 ? "<15" : (prediction_arr===1 ? "[15; 45]" : ">45"),

    chartDataWake: [
      ...prevState.chartDataWake,
      wake: prevState.wake===84.73 ? "H" : (prevState.wake===14.78 ? "M" : "L"), delay: prediction_arr
    ],

    chartDataTurnaround: [
      ...prevState.chartDataTurnaround,
      turnaround: prevState.schedTurnd, delay: prediction_arr
    ]
  ));
;

【讨论】:

【参考方案3】:

您应该使用 setState 的回调,它获取先前的状态作为参数。

this.setState((prevState,props) => 
(
   chartDataWake:[...prevState.chartDataWake, wake: prevState.wake===84.73 
       ? "H" : (prevState.wake===14.78 ? "M" : "L"), delay: prediction_arr],
   chartDataTurnaround = [...prevState.chartDataTurnaround, turnaround: 
      prevState.schedTurnd, delay: prediction_arr],
   prediction_arr: prediction_arr,
   prediction_dep: prediction_dep,
   delay_arr_cat: prediction_arr===0 ? "<15" : (prediction_arr===1 ? "[15; 
      45]" : ">45")
)

【讨论】:

以上是关于setState():不要直接改变状态。使用 setState()的主要内容,如果未能解决你的问题,请参考以下文章

不要直接改变状态,在 React JS 中使用 setState() react/no-direct-mutation-state

如何在我的示例中正确使用 setState()?

为啥这被算作变异状态?

ReactJS:为啥我不应该改变嵌套状态?

更新状态 - 为啥在调用 setState 时创建新的状态副本?

React 组件中的state和setState