Nuxt.js: Can't mutate a module's store state server-side

Created on 17 Aug 2018  路  5Comments  路  Source: nuxt/nuxt.js

Version

any

Reproduction link

https://github.com/paulgv/nuxt-fetch-issue

Steps to reproduce

git clone [email protected]:paulgv/nuxt-fetch-issue.git
cd nuxt-fetch-issue
yarn && yarn dev

http://localhost:3000/

What is expected ?

When committing mutations in the fetch() or nuxtServerInit() methods page should render with mutated state. You should see mutated instead of not mutated on the homepage.

What is actually happening?

The state is actually not mutated and stays at its original value (not mutated) unless the mutation is triggered via a client-side method or if you navigate yo another page then back to the page where fetch() is defined.
If you disable Javascript and refresh the page, you'll notice that the state IS mutated server-side but is then immediately reverted to its original value on the client-side.

Additional comments?

  • Tested with Nuxt 1.4.2 and nuxt-edge.
  • No problem when the mutation happens in the main project's state and not in a module

This bug report is available on Nuxt community (#c7598)
bug-report

Most helpful comment

Hey @paulgv :)

I see what happens here, it is because the plugin is called (the one that registers the Vuex module) on client-side after hydrating the store (See https://github.com/nuxt/nuxt.js/blob/dev/lib/app/index.js#L148-L163).

But Vuex offers a solution for preserving the state from server-side rendering: https://vuex.vuejs.org/guide/modules.html#dynamic-module-registration

screen shot 2018-08-21 at 16 13 20

So here your plugin code updated to works (I tested it):

export default async function ({ router, store }) {
  store.registerModule('simpleModule', {
      namespaced: true,
      state: () => ({
        mutateMe: 'not mutated',
      }),
      actions: {
        mutate ({ commit }) {
          commit('mutate')
        }
      },
      mutations: {
        mutate (state) {
          console.log(state)
          state.mutateMe = 'mutated';
        }
      }
    }, { preserveState: process.browser })
}

All 5 comments

Hey @paulgv :)

I see what happens here, it is because the plugin is called (the one that registers the Vuex module) on client-side after hydrating the store (See https://github.com/nuxt/nuxt.js/blob/dev/lib/app/index.js#L148-L163).

But Vuex offers a solution for preserving the state from server-side rendering: https://vuex.vuejs.org/guide/modules.html#dynamic-module-registration

screen shot 2018-08-21 at 16 13 20

So here your plugin code updated to works (I tested it):

export default async function ({ router, store }) {
  store.registerModule('simpleModule', {
      namespaced: true,
      state: () => ({
        mutateMe: 'not mutated',
      }),
      actions: {
        mutate ({ commit }) {
          commit('mutate')
        }
      },
      mutations: {
        mutate (state) {
          console.log(state)
          state.mutateMe = 'mutated';
        }
      }
    }, { preserveState: process.browser })
}

This bug-report has been cancelled by @Atinux.

Not a bug, only a SSR caveat :)

Awesome! Thanks @Atinux !

With https://github.com/nuxt/nuxt.js/pull/3909, you won't have to give the 3rd option with Nuxt 2.0 @paulgv :)

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredreich picture jaredreich  路  3Comments

vadimsg picture vadimsg  路  3Comments

nassimbenkirane picture nassimbenkirane  路  3Comments

surmon-china picture surmon-china  路  3Comments

o-alexandrov picture o-alexandrov  路  3Comments