pinia-plugin-persistedstate icon indicating copy to clipboard operation
pinia-plugin-persistedstate copied to clipboard

[core] Watch localstorage for changes from other tabs

Open rudolfbyker opened this issue 1 year ago • 6 comments

Clear and concise description of the problem

pinia-plugin-persistedstate is ensuring that when something changes in Pinia, it is written to localstorage. But when another tab running the same web app changes something in localstorage, it is not detected by pinia-plugin-persistedstate. (Remember that localstorage is shared over all tabs that are running the same web app.)

Suggested solution

  • Use any kind of messaging between tabs to say to all other tabs: "Update Pinia from localstorage now" whenever we make a change in localstorage. The https://www.npmjs.com/package/broadcast-channel package makes this easy.
  • Alternatively, add to the pinia-plugin-persistedstate documentation how to set up pinia-shared-state in such as way as to play nicely with pinia-plugin-persistedstate to achieve the same effect.

Alternative

I'm currently using pinia-shared-state to work around this problem. It sends a Broadcast to update the pinia values in other tabs. It also has an option for using localstorage instead of Broadcast to do the updates. The made me think that, if we could just listen to the localstorage updates like they do in pinia-shared-state, we would not need pinia-shared-state for the stores that are already using pinia-plugin-persistedstate with localstorage.

Additional context

No response

Validations

  • [X] Follow our Code of Conduct
  • [X] Read the Contributing Guide.
  • [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

rudolfbyker avatar Nov 08 '23 08:11 rudolfbyker

That's interesting, I'm just curious about performance impact of pushing this as a base feature when it can be added with another plugin. My take would be to make sure it works well with other plugins more than adding it in persistedstate 🤔

Also it's really storage-dependant, and would not work as easily with other storages, making the option dependant on another 🤔

prazdevs avatar Jan 03 '24 01:01 prazdevs

Alternatively instead of broadcasting you can just use the storage event to listen for changes in localstorage from other tabs.

rijenkii avatar Jan 09 '24 02:01 rijenkii

We may consider doing so at present.

const store = useStore()
// ... Other store ...
window.onstorage = ({key}) => {
  switch (key) {
    case <StorePersistKey>:
      store.$hydrate()
      break;
    // ... Other store case ...
}

// Or, addEventListener() for each store
// The advantage is that it can be written together with the store declaration.
const store = useStore()
window.addEventListener('storage', (e) => {
  if (e.key === <StorePersistKey>) {
    store.$hydrate()
  }
})

Of course, I also believe that having it as an optional configuration is essential, as it can help avoid having to write this externally for each store.

AuroraTea avatar Mar 16 '24 06:03 AuroraTea

Is there anyone working on this issue? It would be super cool to have this as a built-in feature.

EgeOnder avatar Mar 18 '24 09:03 EgeOnder

Is there anyone working on this issue? It would be super cool to have this as a built-in feature.

Me.

Currently, progress is stuck at watching of cookies.

AuroraTea avatar Mar 18 '24 11:03 AuroraTea

I tried pinia-shared-state, but I had a few problems with it 1.use native type data loss after refreshing 2.use localstorage type data sometime wirte data missing 3.use idb type keep reporting errors.

Hiram-Wong avatar May 31 '24 16:05 Hiram-Wong

vueuse的useLocalStorage函数可以实现监听LocalStorage里值的变化,不知有没有参考价值。

luwenhegithub avatar Jul 15 '24 04:07 luwenhegithub

这个功能其实挺重要的

luwenhegithub avatar Jul 15 '24 04:07 luwenhegithub