Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useLocalStorage should sync with localStorage #1504

Closed
4 tasks done
jd-solanki opened this issue Apr 19, 2022 · 15 comments
Closed
4 tasks done

useLocalStorage should sync with localStorage #1504

jd-solanki opened this issue Apr 19, 2022 · 15 comments
Labels
enhancement New feature or request

Comments

@jd-solanki
Copy link
Contributor

Clear and concise description of the problem

I am using the card code component which lets you change the code language ts or js. I use useLocalStorage in my card component to get and set language to show in the card.

However, If I change the language from one card then it doesn't get reflected in other cards until I refresh or come back from another route.

Playground

Suggested solution

useLocalStorage can accept a arg to allow sync between instances.

Alternative

None

Additional context

No response

Validations

@jd-solanki jd-solanki added the enhancement New feature or request label Apr 19, 2022
@climba03003
Copy link
Contributor

I am facing the similar issue. The problem should be the localStorage do not update instantly or it wait too long to update. I assume it is the problem of using watchPausable.

@gehringf
Copy link

gehringf commented May 11, 2022

If possible you should share the ref in a separate composable in this case (e.g.

export function usePreferredLanguage() {
  return {
    lang: useStorage('preferredCodeLanguage', 'ts')
  }
}

then in your component

const { lang } = usePreferredLanguage();

@robokozo
Copy link

Ran into this myself today. Glad to see it's already on github!

@dajpes
Copy link

dajpes commented Jul 27, 2022

Do we have a solution for this?

@stale
Copy link

stale bot commented Sep 26, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 26, 2022
@jd-solanki
Copy link
Contributor Author

👀

@stale stale bot removed the stale label Sep 26, 2022
@antfu antfu added the no stale label Sep 26, 2022
@nolde
Copy link

nolde commented Oct 18, 2022

I have been experiencing this with vue3 as well... if you reload the page, value loads correctly, but never seems to track value until next reload.

@harmyderoman
Copy link
Contributor

harmyderoman commented Oct 22, 2022

I'm not sure if this is possible. The problem is in the storage listeners, as it is written in the MDN docs, they will not work on the same page, only on different tabs.

@nolde
Copy link

nolde commented Oct 24, 2022

@harmyderoman You're correct. I was not aware of that.

Probably would be good to add a disclaimer to the doc. I totally expected it to be fully reactive within the context of the same page. Guess I am out of luck.

@harmyderoman
Copy link
Contributor

@nolde don't be upset. Vueuse already has a solution for you. Just use createGlobalState. Like this

// store.js
import { createGlobalState, useStorage } from '@vueuse/core'

export const useGlobalState = createGlobalState(
  () => useStorage('vueuse-local-storage', 'initialValue'),
)

@nolde
Copy link

nolde commented Oct 25, 2022

@harmyderoman Ooooh that's interesting. I'll take a look into that! Thanks a lot mate!

@harmyderoman
Copy link
Contributor

#1595

@pionxzh
Copy link

pionxzh commented Nov 20, 2022

Personally, I do monkey patching on storage.setItem and storage.removeItem.
BUT, you need to do the dedup by yourself to stop the infinity updating.
In the end, I wrote one useLocalStorage by myself :/

For people who want to try this method:

It's definitely not an ideal solution

function hookBefore(target: any, methodName: string, hookFn: Function) {
    const original = target[methodName]
    target[methodName] = function (...args: any[]) {
        hookFn(...args)
        return original.apply(this, args)
    }
}

function tryPatchLocalStorage() {
    // @ts-expect-error mark it as patched
    if (localStorage.setItem.__patched__) return
    // @ts-expect-error mark it as patched
    localStorage.setItem.__patched__ = true

    hookBefore(localStorage, 'setItem', (key: string, newValue: string) => {
        const oldValue = localStorage.getItem(key)
        const event = new StorageEvent('storage', {
            key,
            newValue,
            oldValue,
            storageArea: localStorage,
        })
        nextTick(() => window.dispatchEvent(event))
    })

    hookBefore(localStorage, 'removeItem', (key: string) => {
        const oldValue = localStorage.getItem(key)
        const event = new StorageEvent('storage', {
            key,
            newValue: undefined,
            oldValue,
            storageArea: localStorage,
        })
        nextTick(() => window.dispatchEvent(event))
    })
}

@smallnine9
Copy link
Contributor

Fixed by 800f74f
Maybe we can close it.

@meshbor
Copy link

meshbor commented Jul 4, 2023

Seems problem is not solved yet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests