【问题标题】:Remove items from the database on leaving or closing the page from a React Component从 React 组件离开或关闭页面时从数据库中删除项目
【发布时间】:2020-06-22 14:49:02
【问题描述】:

我有一个 React 组件,它是 React/Apollo Booking 应用程序的一部分。我将所有预订存储在与 React-Apollo 连接的 SQL 数据库中。在客户开始付款过程之前,数据库会发送临时预订以“保留”某些时间并限制其他客户同时预订。如果客户刷新/离开页面,我想从 Apollo DB 中删除这些临时预订。

工作流程如下:

  1. 选择预订时间(这里我将预订添加到数据库)。
  2. 列出客户预订以供审核并添加额外功能。
  3. 付款流程

所以我遇到的问题是,如果客户在第 2 步离开,那么我想从数据库中删除这些预订。这可以像下面的代码那样完成,还是我需要在这些临时预订上设置一个计时器,如果不满足某些条件,在一定时间后从数据库中删除?

我已阅读有关该主题的几个主题并尝试了建议的解决方案。我猜对数据库的调用是异步的,或者涉及道具的事实是问题所在,这就是它不起作用的原因。

componentDidMount() {
    window.addEventListener('beforeunload', function () {
      this.props.tempBookings.forEach(booking => {
        removeBookingFromDB(booking.id)
      })
    }, false);
  }

  componentWillUnmount() {
    window.addEventListener('beforeunload', function () {
      this.props.tempBookings.forEach(booking => {
        removeBookingFromDB(booking.id)
      })
    }, false)
  }

【问题讨论】:

  • 你说的数据库是什么意思?您的 Apollo 商店是否在页面重新加载之间保持不变?
  • 更新了问题,但它是一个 postgres 数据库,在客户开始付款流程之前,预订作为预订存储在数据库中。 [1。选择预定时间] -> [2.查看您的预订和额外功能] -> [3.付款流程] 因此,如果客户在第 2 步中退出流程,要么重新加载页面,要么完全离开页面。我希望将这些预订从数据库中删除。
  • 您应该知道,在beforeunload 处理程序中发出的请求不能保证成功完成。因此,您不能仅仅依靠它,无论如何您都必须实施后备以对该预订保留进行超时。
  • 好的,好点。但我遇到的问题是我没有得到 beforeunload 部分对我来说根本不起作用。
  • removeBookingFromDB 会发生什么?你确定它真的被调用了吗?此外,您可能打算在componentWillUnmount 中调用removeEventListener

标签: reactjs react-router react-apollo react-lifecycle


【解决方案1】:

您作为beforeunload 事件回调提供的函数未绑定到this。改用箭头函数:

window.addEventListener('beforeunload', () => {
    this.props.tempBookings.forEach(booking => {
        removeBookingFromDB(booking.id)
    })
}, false);

要在卸载时正确删除监听器,您需要将处理程序绑定到组件实例,以便您可以在componentWillUnmount 中引用它:

class MyComponent extends React.Component {

    // must be an arrow function
    removeBookings = () => {
        this.props.tempBookings.forEach(booking => {
            removeBookingFromDB(booking.id)
        })
    }

    componentDidMount() {
        window.addEventListener('beforeunload', this.removeBookings, false);
    }

    componentWillUnmount() {
        window.removeEventListener('beforeunload', this.removeBookings, false)
    }
}

【讨论】:

  • 是的,这个改变让它起作用了!但是我不能在生命周期事件中使用类方法,所以我必须在生命周期方法中定义两次函数,但现在它确实有效,感谢您的帮助!
  • @SebastianBerg 定义它两次不会产生预期的效果。 removeEventListener 期望引用您之前注册的相同函数。卸载页面时,不删除处理程序可能会导致内存泄漏和控制台中的警告。请注意,我使用箭头函数来定义removeBookings。除非您使用this.removeBookings = this.removeBookings.bind(this) 将其绑定到类的构造函数中的this,否则它将不适用于普通函数定义。
  • 是的,你又是对的。通常我知道这些事情,但似乎我昨天只是把头放在后面或其他东西=)现在它完全按预期工作,非常感谢您的耐心和您在这里帮助我的时间。
猜你喜欢
  • 2016-12-22
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
相关资源
最近更新 更多