https://codesandbox.io/s/jovial-cannon-iirhd
State of the module registered dynamically is available on the vuex store instance.
console.log message:
// dynamic module state: {
// foo: 'bar'
// }
State of the module registered dynamically is not available on the vuex instance.
console.log message:
//dynamic module state: undefined
This behaviour is visible only when fetch is called on client-side. When the user refreshes the page and fetch is called on server-side everything works as expected.
TLDR;(Fix):
Explicitly add { preserveState: false } to registerModule function. ex.
fetch(context) {
context.store.registerModule(storeNamespace, store, { preserveState: false })
}
Explanation:
I'm not so familiar with Nuxt.js codebase but it seems that this problem might be caused by that line:
https://github.com/nuxt/nuxt.js/blob/a3fdba885e43a76ad605f21d0cfe95038b2681a2/packages/vue-app/template/index.js#L76-L80
In that line, it seems that Nuxt.js overwrites default behaviour of store.registerModule method. Because of that by default, any call to registerModule() will contain also 3rd argument - { preserveState: true/false} depending on current environment (client-side - true, server-side - false). In that case, if you are trying to register a new dynamic module inside fetch and the user navigates from page A to page B fetch will be called on client-side which means that new module will try to preserve existing state which results in not adding dynamic module's state to the store (which is correct vuex behaviour)
PS. In most of the cases, it's probably a better idea to register store module inside plugins (like that store hydration will work out of the box) however in our case it's a bit more complex so we wanted to keep that logic at the "Page" level 馃檪
Thanks for your contribution to Nuxt.js!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you would like this issue to remain open:
Issues that are labeled as pending will not be automatically marked as stale.
Hi,
I'd like to reopen the issue, as it is still present and reproducible with the reproduction provided by OP. I just spent a few hours digging into why my dynamic module doesn't register state properly, and what OP wrote is exactly my conclusion.
I'm loading reusable dynamic module via this.$store.registerModule when an user opens modal, in created lifecycle hook of the modal component. To my knowledge this use-case can not be achieved without passing { preserveState: false }.
Like OP I'm not familiar with Nuxt codebase, if easy fix is not possible, please consider documenting the problem and solution :)
I ran into a similar issue when trying to register a Vuex module client side, not necessarily related to asyncData or fetch. I think the base options of { preserveState: process.client } are a bit heavy handed here in that they assume the SSR render always includes the module state. There are valid use-cases to lazily register a client side module where there is no existing state from SSR. Consider launching a modal and wanting to manage the modal through a new, lazily loaded and registered Vuex module. There wouldn't be any need to pre-register the module during SSR. But if preserveState is false, then Vuex never commits the new namespaced module to the store state, so it's not in the reactive store.state after the call
We're migrating a custom Vue SSR app over to Nuxt at the moment, and our built-in handling for this so far has always been to set preserveState based on the existence of the root module entry for the state (we namespace all of our modules at the moment, so this solution might be limited to namespaced modules):
function registerModule(path, rawModule, options = {}) {
const moduleState = path.reduce((acc, k) => acc && acc[k], this.state);
return originalRegisterModule.call(this, path, rawModule, {
preserveState: moduleState != null,
...options,
});
}
Here's a small codepen demonstrating the issue and fix: https://codepen.io/brophdawg11/pen/LYRVwVX
@Atinux If this makes sense, I'd be happy to open a PR to try to tackle this - let me know 馃憤