React JS:setState中的previousState在状态更新后不保留先前状态的数据

Posted

技术标签:

【中文标题】React JS:setState中的previousState在状态更新后不保留先前状态的数据【英文标题】:React JS: previousState in setState is not keeping the data of the previous state after the state is updated 【发布时间】:2018-11-24 21:39:33 【问题描述】:

我遇到了一个问题,即previousState 在每次更新状态时都不会保留先前状态的数据。当我用新数据更新状态时,之前的状态被清除,只有最近添加的数据可用。

这是第一段代码。这个获取请求在componentDidMount()内部,所以每次刷新组件时,它都会重新获取新数据并更新状态:

fetch('/mileage-data')
    .then(res => res.json())
      .then(data => 
        const state = this.state;
        const test = data.data.startingOdo;
        const test2 = data.data.endingOdo;

        if(!state.startingOdometer || !state.startingOdometer) 
          this.setState( 
            startingOdometer: data.data.startingOdo,
            endingOdometer: data.data.endingOdo
          )
        

        this.setState(prevState => (
          startingOdometer: [...prevState, test],
          endingOdometer: [...prevState, test2]
        ))

      )
      .catch(err => 
         console.log(err);
      )

这就是状态的样子:

this.state = 
  startingOdometer: '',
  endingOdometer: ''

首先,我检查初始状态是否未定义,如果是,则省略之前的状态,只添加新数据。

我的理解是你不应该改变状态,所以使用push() 之类的东西来创建一个数组似乎与此不一致。我的想法是,通过使用先前的状态,我可以制作一个全新的更新版本的状态,其中包括数组中的先前和新数据。

注意:我使用 Postman 检查了这个 /mileage-data GET 路由,它确实按我的预期发回了数据。所以我知道有数据被发送回这个获取请求。

这是我遇到问题的地方:

this.setState(prevState => (
  startingOdometer: [...prevState, test],
  endingOdometer: [...prevState, test2]
))

我的理解是,这应该是创建一个数组,展开操作符会将前一个数组的所有内容,与新的数据组合成一个新的数组。但是当我console.log出数据更新后的状态时,状态只包含当前添加的数据,不保留之前的数据。

我确定我在这里遗漏了一些东西,或者我的方法可能不好。我通过 SO 的运气为零。现在住了两晚,试图解决这个问题!无论如何,提前谢谢你!

【问题讨论】:

"但是当我在数据更新后 console.log out 状态" 发生在哪里?我在您的代码示例中没有看到这一点。您可能会遇到setState 不会立即更新状态的事实。见here 为简洁起见,我省略了其他几个。 【参考方案1】:

试试:

 this.setState(prevState => (
      startingOdometer: [...prevState.startingOdomoter, test],
      endingOdometer: [...prevState.endingOdometer, test2]
    ))

此外,您可能会丢失承诺中 this 关键字的上下文。尝试将 let that = this 放在 fetch 调用上方,如果仍然无法正常工作,请使用 that.setState

【讨论】:

【参考方案2】:

我假设 data.data.startingOdo 是一个对象。有时将它设置为一个对象并排列其他对象是没有意义的。

据我所知,您只需要不断将新数据添加到数组中即可。为什么不是这个?

此外,如果您需要在卸载和重新安装组件时保持状态,您需要查看某种类型的全局状态管理,例如 redux。

// set initial state to empty arrays
state = 
  startingOdometer: [],
  endingOdometer: [],


fetch('/mileage-data')
.then(res => res.json())
  .then(data => 
    const startingOdometer, endingOdometer = this.state;

    this.setState( 
      startingOdometer: [...startingOdometer, data.data.startingOdo],
      endingOdometer: [...endingOdometer, data.data.endingOdo],
    )

  )
  .catch(err => 
     console.log(err);
  )

【讨论】:

'坚持'。这就是我一直在寻找的词。我需要状态在整个用户会话中持续存在,然后当他们注销时,状态中的数据将保存到数据库中。我对 Redux 不太熟悉,所以这可能只是我不知道什么时候应该使用 Redux。

以上是关于React JS:setState中的previousState在状态更新后不保留先前状态的数据的主要内容,如果未能解决你的问题,请参考以下文章

React JS:setState中的previousState在状态更新后不保留先前状态的数据

React.js状态值为数组,怎么使用setState比较合适

[react] react中的setState是同步还是异步的呢?为什么state并不一定会同步更新?

JS每日一题: 如何理解react中setState?

在 React JS 的 this.setState 的回调中使用 this.setState?

React.js setState() 与循环内的键变量?