Vuex: registerModule with option { preserveState: true } not working

Created on 10 Jan 2018  路  2Comments  路  Source: vuejs/vuex

Version

3.0.1

Reproduction link

https://github.com/Serhiy-Nazarov/demo-error-with-vuex-register-module/blob/master/src/store/index.js

Steps to reproduce

git clone [email protected]:Serhiy-Nazarov/demo-error-with-vuex-register-module.git
yarn install
yarn dev

After this, open a console in the browser an look to messages.

What is expected?

two modules will be registered

What is actually happening?

Only first module (with preserveState: false) is registered

Most helpful comment

You are misunderstanding what preserveState does, and what it's for:

When you set preserveState: true, the module is registered - actions, mutations and getters are added to the store (you can verify this in your reproduction by adding an action that logs to console and dispatching it).

But the state is skipped, because it's assumed that your store state already contains state for that module (usually from from using SSR to render the app from the server) and you don't want to overwrite it - you want to preserve it.

We could add a check to see if that state is really already there, and if it's not, add it after all - but that's something that you can do yourself pretty easily:

preserveState: !!store.state.test2

All 2 comments

You are misunderstanding what preserveState does, and what it's for:

When you set preserveState: true, the module is registered - actions, mutations and getters are added to the store (you can verify this in your reproduction by adding an action that logs to console and dispatching it).

But the state is skipped, because it's assumed that your store state already contains state for that module (usually from from using SSR to render the app from the server) and you don't want to overwrite it - you want to preserve it.

We could add a check to see if that state is really already there, and if it's not, add it after all - but that's something that you can do yourself pretty easily:

preserveState: !!store.state.test2

@LinusBorg why do the docs on store code splitting suggest that serverPrefetch should register with { preserveState: true } then? On the server, there is no state yet, and as such, this fails.

In the docs example, it's serverPrefetch ==> this.registerFoo() ==> this.$store.registerModule('foo', fooStoreModule, { preserveState: true }). It doesnt make sense that both client + server share the same registerFoo() function

Thanks!


For anyone struggling with this, here's the fixed setup I am using, including dynamic store module loading:

import foo_store_module from '@/store/foo-store'
export .....
    // Server
    async serverPrefetch() {
        await this.fetch_data()
    },
    computed: {
        data_fetched() {
            return this.$store.state.foo?.some_data?.length
        }
    },
    // Server + client (before hydration)
    created() {
        this.$store.registerModule 'foo', foo_store_module, { preserveState: !!this.$store.state.foo }
    },
    // Client (after hydration)
    async mounted() {
        if(!this.data_fetched)
            await this.fetch_data()
    },
    destroyed() {
        this.$store.unregisterModule 'foo'
    }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Ge-yuan-jun picture Ge-yuan-jun  路  3Comments

james-wasson picture james-wasson  路  3Comments

gdelazzari picture gdelazzari  路  3Comments

mbana picture mbana  路  3Comments

blocka picture blocka  路  4Comments