state returned as function or object literal

I ran into a problem the other day, and asked the great stack community for a solution.

The problem:

I nested the same module in other modules but I was defining state in this way:

state: {
  // some state here
}

What was happening is all of my modules despite seeming being nested under disparate modules all shared the same state.

The solution

state() {
  return {
    // state here instead
  }
}

The solution is to have a function return state rather than define it as an object literal. The why somewhat makes sense. Here are my questions

New questions

  • What is happening under the hood of the store when state is defined as an object literal versus a function returning an object literal?

  • Why would you ever not use the function version? It seems like easily the default choice, but even in vuex docs for modules , they opt to show state as an object literal.


  • tl;dr The reason for using a function is Module Reuse .


    What is happening under the hood of the store when state is defined as an object literal versus a function returning an object literal?

    For that, better check under the hood:

    var Store = function Store (options) {
      // ...
      var state = options.state; if ( state === void 0 ) state = {};
      if (typeof state === 'function') {
        state = state() || {};
      }
    

    The code above, as you can see, checks if a state was provided. If not, it assigns an empty object ( {} ) as initial state .

    Next it checks if state was a function . If it was, it executes it and assigns to state what it returned. If it returned undefined (or any falsy value) it, again, assigns to state the empty object {} .

    So that's the difference between providing state as an object or function: if one was provided, it is executed. If an object is provided, it is assigned directly.


    Why would you ever not use the function version? It seems like easily the default choice, but even in vuex docs for modules, they opt to show state as an object literal.

    In general, yes, the object version may be more common, because you typically only declare the store object (and its state ) once and just use it in your Vue instance.

    A use case for the state function, otoh, is Module Reuse :

    Module Reuse

    Sometimes we may need to create multiple instances of a module, for example:

  • Creating multiple stores that use the same module (eg To avoid stateful singletons in the SSR when the runInNewContext option is false or 'once');
  • Register the same module multiple times in the same store.
  • Another possible case would be if you declared a Vuex module just once and attempted to use it more than one time under different namespaces .

    As the examples above are similar, here's a demo (of the module case) to illustrate the problem:

    const personModule = {
      namespaced: true,
      state: {name: "name"},
      mutations: {
      	changeName(state, data) { state.name = data }
      }
    }
    const myStore = new Vuex.Store({
      strict: true,
      modules: {
        aliceNamespace: personModule,
        bobNamespcace: personModule
      }
    });
    new Vue({
      store: myStore,
      el: '#app',
      mounted() {
        this.changeAlicesName("Alice");
        this.changeBobsName("Bob");
      },
      computed: {
        ...Vuex.mapState('aliceNamespace', {alicesName: 'name'}),
        ...Vuex.mapState('bobNamespcace', {bobsName: 'name'})
      },
      methods: {
        ...Vuex.mapMutations('aliceNamespace', {changeAlicesName: 'changeName'}),
        ...Vuex.mapMutations('bobNamespcace', {changeBobsName: 'changeName'})
      }
    })
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <p>Alice's name: {{ alicesName }}</p>
      <hr>
      <p>Bob's name: {{ bobsName }}</p>
      <hr>
      <button @click="changeAlicesName('Eve')">Change Alice's Name</button>
    </div>
    链接地址: http://www.djcxy.com/p/41424.html

    上一篇: docker中的“精简池”是什么意思?

    下一篇: 状态作为函数或对象文字返回