【问题标题】:What is prevState in ReactJS? [duplicate]ReactJS 中的 prevState 是什么? [复制]
【发布时间】:2019-07-15 09:20:23
【问题描述】:

我认为问这个问题可能很愚蠢,但相信我,我是 reactJS 的初学者。有人可以解释一下为什么我们在 ReactjS 中使用 prevState 。我努力理解但失败了。

这是我的代码。请帮助我理解

 state = {
    placeName : '',
    places : []
}



placeSubmitHanlder = () => {
    if(this.state.placeName.trim()===''){
      return;
    }
    this.setState(prevState => {
      return {
        places : prevState.places.concat(prevState.placeName)
      };
    });
  };

【问题讨论】:

  • 我不认为这篇文章是它声称是副本的链接帖子的 1:1 副本。一方面,当您应该在 SO 上的每个帖子问 1 个问题时,链接的帖子会同时提出 三个 问题。这篇文章的重点是像我这样的新手在学习时提出的一个问题。所有这一切中最丰富的部分是 prevState 没有在反应文档中明确讨论。这篇文章的当前最佳答案详细说明了 prevState 比这篇文章的链接帖子是假定的副本或反应文档更进一步。

标签: javascript reactjs react-native


【解决方案1】:

prevState 是您为传递给 setState 回调函数的参数指定的名称。它持有的是setState 被 React 触发之前的状态值;由于setState 进行批处理,当您想根据之前的状态值更新新状态时,了解之前的状态有时很重要。

因此,如果多个 setState 调用更新同一个状态,批处理 setState 调用可能会导致设置不正确的状态。举个例子:

state = {
   count: 0
}
updateCount = () => {
    this.setState({ count: this.state.count + 1});
    this.setState({ count: this.state.count + 1});
    this.setState({ count: this.state.count + 1});
    this.setState({ count: this.state.count + 1});
}

在上面的代码中,您可能期望 count 的值为 4,但实际上它是 1,因为最后一次调用 setState 将覆盖批处理期间的任何先前值。解决这个问题的一种方法是使用函数式 setState:

updateCount = () => {
    this.setState(prevstate => ({ count: prevstate.count + 1}));
    this.setState(prevstate => ({ count: prevstate.count + 1}));
    this.setState(prevstate => ({ count: prevstate.count + 1}));
    this.setState(prevstate => ({ count: prevstate.count + 1}));
}

【讨论】:

  • 知道了,谢谢。最后一个问题 。你能解释一下这段代码吗? this.setState(prevState => { return { places : prevState.places.concat(prevState.placeName) }; });
  • 您可以查看this问题了解更多详情
  • 其实我理解了幕后的一切,但在这条线上混淆了prevState.places.concat这是什么意思。谢谢
  • prevState.places.concat(prevState.placeName) 会将 state 中之前的 placeName 值推送到 places 状态数组并返回一个新数组,我们用它来设置 places 状态
  • 抱歉不明白..
【解决方案2】:

这是一个带有注释代码的演示,可提供更多信息:http://codepen.io/PiotrBerebecki/pen/rrGWjm

constructor() {
  super();
  this.state = {
    value: 0
  }
}

React 文档:https://facebook.github.io/react/docs/reusable-components.html#es6-classes

[React ES6 类] API 与 React.createClass 类似,但 getInitialState 除外。您无需提供单独的 getInitialState 方法,而是在构造函数中设置自己的 state 属性。

prevState 从何而来?

prevState 来自 setState api:https://facebook.github.io/react/docs/component-api.html#setstate

也可以传递带有签名函数(状态,道具)的函数。在某些情况下,当您希望在设置任何值之前将查询 state+props 的先前值的原子更新排入队列时,这可能很有用。例如,假设我们想在 state 中增加一个值:

this.setState(function(previousState, currentProps) {
  return {
     value: previousState.value + 1
  };
});

【讨论】:

  • 您能否解释一下先前值的含义以及该值的来源? .
  • @user11037643 react 在内部将“this.state”作为“previousState”。顺便说一句,正如 S.Haviv 和 Shubham Khatri 解释的那样,为了覆盖批处理,您必须传递一个函数而不是一个 obj。
  • @user11037643 这里是 'setState' 实际上在 ``` setState( state: ((prevState: Readonly, props: Readonly

    ) => (Pick | S | null)) | (Pick | S | null), callback?: () => void ): void;``` 所以你的```状态= { placeName : '', places : [] }``` 将是您的 'previousState' 或您为回调函数的第一个参数输入的任何变量名称 (function(previousState, currentProps) { return { value: previousState.value + 1 }; })

【解决方案3】:

当你想用最后一个状态的参数覆盖当前状态时使用它。

来自 React 文档:

根据 React 文档,“React 可以将多个 setState() 调用批处理到单个更新中以提高性能。因为 this.propsthis.state 可能会异步更新,因此您不应依赖它们的值来计算下一个状态。 "

“要修复它,请使用setState() 的第二种形式,它接受一个函数而不是一个对象。该函数将接收以前的状态作为第一个参数,并将应用更新时的道具作为第二个参数论据”

Link

【讨论】:

  • @S.Haaviv 感谢您的评论。您能否解释一下您在回答中提到的“先前状态值”。我的代码中出现了以前的状态。
  • 当你使用 setState 设置一个新的状态时,prevState 是当前状态(在 setState 的函数内部)。因为 react 可以做一些批处理并且它是异步的,所以状态可能会随着时间而改变,所以你不能依赖它。
猜你喜欢
  • 2023-01-16
  • 2022-12-04
  • 2016-08-04
  • 2019-11-12
  • 2019-09-13
  • 2019-05-02
  • 2020-05-23
  • 2017-02-15
  • 2018-06-11
相关资源
最近更新 更多