vueuse icon indicating copy to clipboard operation
vueuse copied to clipboard

BUG | `useStorage` | The new value is ignored when changing both the key and value synchronously

Open gkubisa opened this issue 9 months ago • 4 comments

Describe the bug

When changing the storage key and then the ref containing the value synchronously, the new value is ignored and the ref contains the value from storage.

Here's what happens when changing both the useStorage key and value synchronously:

  1. Set the key and value.
  2. The key watcher triggers update.
  3. The update function loads the value from the storage and sets the value (data).
  4. The data watcher triggers write.
  5. The write function updates the storage with the value loaded from the storage in step 3 (not expected), rather than with the value explicitly set in step 1 (expected).

Reproduction

https://playground.vueuse.org/#eNqVVcFu2zgQ/RVCFyWAK223PXndINkih+wu2kVb7F50YcSJxIQiCXLk2DD87x2SsiQ7beGcLM48vvc4HI532Y21xbqHbJmtfO2kReYBe8sU182HKkNfZVeVlp01DtmO9R7+MTVXX9E43gDbswdnOpZfEwflyto4yGd433KlzPMXeBihhCREpWujPbIn2N5piZIr9oHlMn3mf8zSH1uyAiKk6/R5lKb4JHIx0V0eMGuueiDUifUAXbA8vySySjugY1+k74de1yiNZkOQ7SrNglRxoJpUaAMLFbtD6GbiRCydAwVrrjFKHKGGIxHq0+dvDDYWaqRjBdz+yEE68N+wvdHivyD+EzcDYdSJ4TGZj+wvyGeGlsyjk7pZMA3PUegQGfRSKX0q3Y0DTtRqVs2onEBGJavhYiZ80UxqQz1myZmVyUKCPUstzHMhpLcc6/Z2DRovCMIG5RTIB7Z8kfzGCi3S18HQsDzQD8uZjRjZXw7XsCrTg6D2pwW5s4oj0IqxlZDrq/9bGC6IysTuDbYMW4gtybUY2s5vdd06o03vFR0tAIL3lJSeaYPMgvPS0xUVqzIQjwqr+x6RLuq6VrJ+otf4oh3ocaarP5ZdlWnnS4bY0rTrS/idYMe6sSF2u8i5358ko0BMp0NMgFU5KxItPW4VVaA2FgRFCJTuxnIhqGRL9t5uUqkHlzF7z+unxpleiyVTsmmxcbCNnXBvnAC3ZG/thnmjpGBj6oTygH3juJC9nynRpQZXV9kiSzPqTcdt8eiNpgkY9ashQYOPTpl6pMoO860D5IIjD8kqaxGtX5ZlLTRxCFBy7QoNWGrbladbrt++K34vfiupn2FTdI8kMLTgRE+TzIF4BXnacA51mMyvIA7wc2ilRmgcDwMlVuxM+vm2c2Q6ju1rak7wc2jdJoTPpg3wH9DGsUHtRU2F1O76QTYnLVWbzkoF7rMdCzW2Vvzv+ivG0I1jKTx2qJ9+EH/0m2T53/CY3ZpudcwhdzRnU/r26yfY0PeY7Izo1dADP0nSWDCqDx4T7E96hmR7hotu7+ILoQf3zd9uELQ/HCoYjdWI+Cqjun38xdEnu++K92MV998BRGL3Nw==

System Info

System:
    OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
    Memory: 4.10 GB / 15.34 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 22.14.0 - /run/user/1000/fnm_multishells/5676_1747894241665/bin/node
    npm: 10.9.2 - /run/user/1000/fnm_multishells/5676_1747894241665/bin/npm
    pnpm: 10.10.0 - /run/user/1000/fnm_multishells/5676_1747894241665/bin/pnpm
  Browsers:
    Chrome: 135.0.7049.114

Used Package Manager

pnpm

Validations

  • [x] Follow our Code of Conduct
  • [x] Read the Contributing Guidelines.
  • [x] Read the docs.
  • [x] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • [x] Make sure this is a VueUse issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/core instead.
  • [x] Check that this is a concrete bug. For Q&A open a GitHub Discussion.
  • [x] The provided reproduction is a minimal reproducible example of the bug.

gkubisa avatar May 22 '25 14:05 gkubisa

As workaround:

const value = useLocalStorage(key, '', {flush: 'sync'});

OrbisK avatar May 22 '25 14:05 OrbisK

/cc @43081j @ferferga IMO we should consider flush sync as default here

OrbisK avatar May 22 '25 14:05 OrbisK

it may be that we just need to document this better.

i feel like the primary use case won't involve doing a key and value change at the same time. so a pre flush default is probably fine for most people

but it isn't clear from the docs that if you want to do this, you need to set flush: 'sync'

43081j avatar May 23 '25 09:05 43081j

In my opinion flush: 'pre' is the perfect default for the value watcher (consistent with Vue, intuitive behavior, good for performance, etc), however, I'd argue that the key watcher should be always flush: 'sync' because:

  • it makes usage easier and more intuitive because after changing the key the new value would be available immediately for reading and writing
  • performance is likely much less of a concern assuming that the key would change much less then the value

So, I'd suggest that maybe we could update https://github.com/vueuse/vueuse/blob/v13.2.0/packages/core/useStorage/index.ts#L182 to watch(keyComputed, () => update(), { flush: 'sync' })?

gkubisa avatar May 23 '25 13:05 gkubisa