Search code examples
javascriptvue.jslocal-storagevueuse

How to Prevent VueUse useStorage from Repopulating localStorage After Clearing localStorage?


I'm using Vue 3 along with VueUse's useStorage to synchronize some reactive state with localStorage. However, I'm encountering an issue where localStorage gets automatically repopulated with previous values after I clear it programmatically during user logout processes. Here’s how I’m currently handling the logout:

import { useStorage, nextTick } from '@vueuse/core';

const userSettings = useStorage('user-settings', {});

async function logoutAndClear() {
  // Reset the user settings before clearing localStorage
  userSettings.value = {}; 

  await nextTick(); // Ensure Vue's reactivity system updates the state

  localStorage.clear(); // Attempt to clear all localStorage items
}

Despite this, localStorage is immediately repopulated with the old user-settings values right after the clear() operation. I suspect this is due to VueUse's reactivity system detecting the change and writing back to localStorage.

How can I effectively clear localStorage without having it immediately repopulated by VueUse's useStorage?


Solution

  • According to the documentation Simply assigning a null value to the state removes it from the storage.

    You are already trying to reset the value of the local storage to an empty object. Instead set it to null.

    const userSettings = useStorage('user-settings', {});
    
    function logoutAndClear() {
      userSettings.value = null; 
    }
    

    If you don't want the code to populate the storage with default value {} after the page refresh, you need to update the initialization to also be null by default.

    const userSettings = useStorage('user-settings', null);
    

    If this is not enough for you, and you really want to clear the entire storage with one call. I recommend changing your approach to storage and keeping all the values inside of a single key, instead of multiple. For instance you could create a key 'my-store' that keeps all the data.

    localStorage.setItem('my-store', '{"hello": "nihao"}')
    
    const state = useStorage(
      'my-store', // key
      { hello: 'hi', greeting: 'hello' }, // default options for storage
      localStorage,
      { mergeDefaults: true } // merge behaviour
    )
    
    console.log(state.value.hello) // 'nihao', from storage
    console.log(state.value.greeting) // 'hello', from merged default value
    

    This would allow you to clear the entire storage as if you were clearing a single key.

    state.value = null;