【问题标题】:React setState in componentDidMount not working在 componentDidMount 中反应 setState 不起作用
【发布时间】:2021-01-29 01:28:15
【问题描述】:

知道为什么跟随 popUpBurned 的 setState 不起作用吗?

 componentDidMount() {
    const { user } = this.props
    const { popUpBurned } = this.state
    const visits = user.visitsCounter

    if (visits === 6 && !popUpBurned) {

      this.setState({ popUpBurned: true })
      this._popupFeedbackVisits.show()
    }

  }

当访问数为 6 时,我需要我的 _popupFeedbackVisits 仅触发一次,这很好。但是当在同一次访问中,用户导航到另一个页面并返回仪表板时,弹出窗口再次触发(因为访问次数仍然是 6)。

如何使弹出窗口触发一次且仅触发一次?我的想法是添加该布尔值,但它似乎在 componentDidMount 中不起作用。我错过了什么?

谢谢!

【问题讨论】:

  • 也许你应该使用像React Redux这样的存储引擎
  • 您能告诉我们您在哪里以及如何设置访问计数器
  • popUpBurned 的初始值是多少?
  • 同意,Redux 可能是一个很好的解决方案,或者新的Context API。另外,考虑将popUpBurned 状态存储在保持挂载的父级中。
  • visits-counter 在 /login 请求中设置并且工作正常。 popUpBurned 的初始值为 false。

标签: reactjs setstate


【解决方案1】:

如果popUpBurned 没有在render 中使用,它可能不需要在state 中,您可以将其设为类属性:

class ... extends React.Component {
    constructor(props) {
        ...
        this.popUpBurned = false
    }

    ...

    componentDidMount() {
        const { user } = this.props
        const visits = user.visitsCounter

        if (visits === 6 && !this.popUpBurned) {
            this.popUpBurned = true
            this._popupFeedbackVisits.show()
        }

    }
}

【讨论】:

  • 你好程序员。不,它不在渲染中。你能解释一下关于制作类属性的更多信息吗?谢谢!
  • 非常感谢程序员,但我正在尝试,但它似乎也不起作用。它仍然是错误的......但学习起来很好,非常值得一试!
【解决方案2】:

我的建议是将popUpBurned 存储在其他地方并将其作为道具传递给该组件。从您的帖子看来,user 是一个全局对象,而且这应该只发生一次。也许将其存储在用户身上是合适的?

componentDidMount() {
    const { user } = this.props
    const visits = user.visitsCounter
    const popUpBurned = user.popUpBurned

    if (visits === 6 && !popUpBurned) {

      this.setState({ popUpBurned: true })
      this._popupFeedbackVisits.show()
    }
}

【讨论】:

  • 您好 Nitsew,非常感谢。是的,用户是全球性的,我将像使用visitsCounter 一样将popUpBurned 存储在那里。但我想知道......为什么componentDidMount里面的settingState这么有问题?我的意思是,这就是它不起作用的原因吗?只是好奇..
  • 它正在读取props.user.popUpBurned,但仍在使用setState 来更改它?
  • @CarlosdelRíoFrancés 在componentDidMount 生命周期方法中调用setState 没有问题,但在您的用例中它不起作用,因为当组件卸载并按照您的描述重新安装时, this.state.popUpBurned 被重置为初始状态值。组件状态不会持久化,这就是为什么您需要将其存储在用户的 sceop 之外的原因。
  • 谢谢!这很有帮助。
【解决方案3】:

您可以尝试更改if语句中的访问次数,使其不再触发相关函数。因为在任何刷新或返回页面时都会让componentDidMount工作,然后继续弹出。

【讨论】:

    【解决方案4】:

    这个使用 sessionStorage 的变通方法解决了这个问题:

    if (user.visitsCounter === 6 && !sessionStorage.getItem('popUpBurned')) {
          sessionStorage.setItem('popUpBurned', true)
    
          this._popupFeedbackVisits.show()
        }
    

    【讨论】:

      猜你喜欢
      • 2016-05-13
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多