简体   繁体   English

通过服务工作者通过用户单击按钮更新 PWA 反应应用程序(使用 CRA)

[英]update PWA react app (using CRA) with user clicked button through service worker

I want to update PWA application when new content is available.当有新内容可用时,我想更新 PWA 应用程序。 Since we can't access DOM from service worker, how can I exactly do that?由于我们无法从 service worker 访问 DOM,我该怎么做呢? The service worker correctly recognize the new content, but I can't bind a hook or context to show my modal or update button in react.服务人员正确识别新内容,但我无法绑定挂钩或上下文以在反应中显示我的模式或更新按钮。 Any help?有什么帮助吗?

service worker register and onUpdate function:服务工作者注册onUpdate功能:

function RegisterValidSW(swUrl, config) {
 navigator.serviceWorker
.register(swUrl)
.then((registration) => {
  registration.onupdatefound = () => {
    const installingWorker = registration.installing;
    if (installingWorker == null) {
      return;
    }
    installingWorker.onstatechange = () => {
      if (installingWorker.state === 'installed') {
        if (navigator.serviceWorker.controller) {
          // At this point, the updated precached content has been fetched,
          // but the previous service worker will still serve the older
          // content until all client tabs are closed.
          // setUpdate(true);
          // registration.waiting.postMessage({ type: 'SKIP_WAITING' });
          console.log(
            'New content is available and will be used when all ' +
            'tabs for this page are closed. See https://cra.link/PWA.'
          );

          // Execute callback
          if (config && config.onUpdate) {
            config.onUpdate(registration);
          }
        } else {
          // At this point, everything has been precached.
          // It's the perfect time to display a
          // "Content is cached for offline use." message.
          console.log('Content is cached for offline use.');

          // Execute callback
          if (config && config.onSuccess) {
            config.onSuccess(registration);
          }
        }
      }
    };
  };
})
.catch((error) => {
  console.error('Error during service worker registration:', error);
});
}

this function is in the serviceWorkerRegistration.js file.这个函数在serviceWorkerRegistration.js文件中。 We can add registration.waiting.postMessage({ type: 'SKIP_WAITING' });我们可以添加registration.waiting.postMessage({ type: 'SKIP_WAITING' }); function to call skipWaiting but it doesn't wait for user interaction and can't reload the page.调用 skipWaiting 的函数,但它不等待用户交互并且无法重新加载页面。 how can I solve that?我该如何解决?

You can try passing in an onUpdate function when you register the service worker.您可以在注册 service worker 时尝试传入 onUpdate 函数。 In that function send a SKIP_WAITING message to the service worker followed a page reload.在该函数中,在页面重新加载后向服务人员发送 SKIP_WAITING 消息。

 onUpdate: (registration) => {
    console.log("SW: sending SKIP_WAITING message to get updated serviceworker to take effect now (without manual restart)")
    // Old serviceworker will be stopped/new serviceworker started without reload
    registration.waiting.postMessage({type: 'SKIP_WAITING'})
    window.location.reload()
}

Your server worker should have SKIP_WAITING message hander.您的服务器工作者应该有 SKIP_WAITING 消息处理程序。 Something like this:像这样的东西:

self.addEventListener('message', (event) => {
console.log("SW: received message event = "+JSON.stringify(event))
if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
}});

This is working for me.这对我有用。

What I am still struggling with is how to get the app updated if the user leaves the app open.我仍在苦苦挣扎的是,如果用户让应用程序保持打开状态,如何更新应用程序。 As in,如中,

  1. User browses to PWA url用户浏览到 PWA url
  2. User adds to Home Screen用户添加到主屏幕
  3. User closes browser tab用户关闭浏览器选项卡
  4. User opens PWA from Home Screen用户从主屏幕打开 PWA

and just leaves it open forever and ever...就让它永远敞开着……

This should probably go in a new question, but I thought it might be relevant to your use case.这可能应该出现在一个新问题中,但我认为它可能与您的用例有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM