Vuex State on Page Refresh

Vuex state on page refresh

This is a known use case. There are different solutions.

For example, one can use vuex-persistedstate. This is a plugin for vuex to handle and store state between page refreshes.

Sample code:

import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'

const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})

What we do here is simple:

  1. you need to install js-cookie
  2. on getState we try to load saved state from Cookies
  3. on setState we save our state to Cookies

Docs and installation instructions: https://www.npmjs.com/package/vuex-persistedstate

Vuex: persisting state on page refresh without writing itvuex?

There are many web APIs you can use to persist some state inside your user's browsers:

  • Local storage
  • Indexed database
  • cookies

There's also a package specifically done for that

Vuex state does not update without a page refresh

local storage isn't a reactive data so when it changes, there is no way for vuex store to get notified.

what happens is that when your app loads getToken() is called at the very beginning and since user isn't logged in yet it returns undefined, when user logs in, local storage is updated but getToken() doesn't get called again.

BUT! now you have the data in your local storage so when you refresh your page manually getToken() is called and return a Truthy value.

what you can do is to write an action to update accessToken and call it when user is logged in.

something like this:

api.getToken(URL, userData).then((result) => {
// if user is logged in successfully call the action
if (result) this.$store.dispatch('auth/updateAccessToken');
})

Vue3 - Persisting state with Page refresh

You can add the created hook to the root component by using the extends option with the component definition:

// main.js
import { createApp } from 'vue'
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from './store'

const store = createStore(storeDefinition)

createApp({
extends: Index,
created() {
this.$store.dispatch('loadStoredState')
this.$store.dispatch('loadUser')
},
})
.use(createRouter())
.use(store)
.mount('#app')

demo

Vuex store empty if i refresh my webpage

To persist state data after app refresh, you can either use localStorage or sessionStorage.

  1. XSS: The problems with storing tokens in localStorage as you say is about the app being vulnerable to XSS (cross-site-scripting) attacks. Apart from that, it is quite safe. The localStorage is bound to the domain, so the data of www.yourapp.com will stay there even after the browser is closed also unlike cookies, you won't have to manage which site made the request. All the tabs on the browser with the same domain will be able to use the data in the localStorage

    If the said behaviour is not needed, you can go for sessionStorage, it works almost the same way but the data gets cleared when the browser is closed.

  2. Going for cookies, sure they will help saving your token being taken away by an XSS but then you will have to ensure you also provide a csrf-token to protect against CSRF (Cross Site Request Forgery) attacks.

    If you plan on going forward with cookies, then make sure they have the httpOnly flag set to true in the headers, else they are no good.

Overall I have seen that localStorage has been a very commonly recommended solution for maintaining tokens and other app data.

I'll add sources to this answer for reference.

  1. CSRF Token necessary when using Stateless(= Sessionless) Authentication?
    Check the accepted answer and others as well.

  2. https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md

  3. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

  4. https://www.whitehatsec.com/blog/web-storage-security/ This would let you know about the pitfalls and how-to for using localStorage.

Why can't I load data from vuex when I refresh site?

Vue is a SPA framework and SPAs doesnot support page refresh.

I recommend you to use vuex-persistedstate npm package to prevent daa loss on page refresh.

https://www.npmjs.com/package/vuex-persistedstate

Eventhough they have stopped the supprt, this still supprts the latest version of Vue JS and VueX

Vuex store not persist 'state' when I refresh or navigate?

Vuex doesn't persist state automatically. You can use the vuex-persistedstate package to achieve this (https://github.com/robinvdvleuten/vuex-persistedstate).

Vuex state is sometimes empty (undefined), especially when I refresh the page and sometimes it works

The getSkills action is performing an asynchronous request. You need to wait for the request to finish before you can access this.Skills otherwise the data will not be set yet.

You need async and await (the "modern" solution):

async mounted() {
await this.getSkils();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
}

or:

mounted() {
this.getSkils().then(() => {
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
});
}


Related Topics



Leave a reply



Submit