如何激活反应路线并传递服务工人的数据?

问题描述 投票:0回答:2

我有一个SPA PWA React应用程序。它已在移动设备(Android + Chrome)上以独立模式安装并运行。

例如,该应用列出了人员,然后当您单击某个人时,它会使用/person路线显示详细信息。

现在,我正在从服务器发送推送通知,并在应用程序附带的服务工作者中接收它们。该通知是关于某人的,当用户单击该通知时,我想打开该人的详细信息。

问题是:

  • 我如何通过服务工作者在我的应用程序上激活/person路由
  • 并传递数据(例如,人员ID或人员对象)
  • 不重新加载应用程序

据我了解,可以从服务工作者notificationclick事件处理程序中获得:

  • 专注于应用程序(但是我如何传递数据并激活路线)
  • 打开一个URL(但是/person不是物理路径,而且无论哪种方式-我都希望避免刷新页面)
reactjs react-router single-page-application service-worker progressive-web-apps
2个回答
0
投票

您可以监听显示给用户的通知的click事件。在处理程序中,您可以通过push事件打开来自服务器的相应人员的URL。

notification.onclick = function(event) {
  event.preventDefault(); 

  // suppose you have an url property in the data
  if (event.notification.data.url) {

      self.clients.openWindow(event.notification.data.url);
  }
}

检查这些链接:


0
投票

要回答我自己的问题:尽管我不太满意,但我已经使用IndexedDB(因为它是同步的,所以不能使用localStorage)在SW和PWA之间进行通信。

这大致就是我的服务工作者代码的外观(我正在使用idb库):

self.addEventListener('notificationclick', function(event) {
    const notif = event.notification;
    notif.close();
    if (notif.data) {
        let db;
        let p = idb.openDB('my-store', 1, {
            upgrade(db) {
                db.createObjectStore(OBJSTORENAME, {
                    keyPath: 'id'
                });
            }
        }).then(function(idb) {
            db = idb;
            return db.clear(OBJSTORENAME);
        }).then(function(rv) {            
            return db.put(OBJSTORENAME, notif.data);
        }).then(function(res) {
            clients.openWindow('/');
        }).catch(function(err) {
            console.log("Error spawning notif", err);
        });
        event.waitUntil(p);
    }
});

然后,在我的React应用程序的根目录中,即在我的AppNavBar组件中,我总是检查是否有需要显示的内容:

componentWillMount() {
    let self = this;
    let db;
    idb.openDB('my-store', 1)
    .then(function (idb) {
        db = idb;            
        return db.getAll(OBJSTORENAME);
    }).then(function (items) {            
        if (items && items.length) {
            axios.get(`/some-additional-info-optional/${items[0].id}`).then(res => {
                if (res.data && res.data.success) {
                    self.props.history.push({
                        pathname: '/details',
                        state: {
                            selectedObject: res.data.data[0]
                        }
                    });
                }
            });
            db.clear(OBJSTORENAME)
            .then()
            .catch(err => {
                console.log("error clearing ", OBJSTORENAME);
            });
        }
    }).catch(function (err) {
        console.log("Error", err);
    });
}

一直在玩弄clients.openWindow('/?id=123');clients.openWindow('/#123');,但是这很奇怪,有时应用程序会停顿,所以我恢复了IndexedDB的方法。(clients.postMessage也可能是我不知道如何将其插入React框架的方法)

还有其他人,我还在寻找更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.