Skip to content

code demo for section 'Store Code Splitting' not valid #240

Open
@dyf19118

Description

@dyf19118

Please refer to this section 'Store Code Splitting'.

{
  // here follows critical code in given demo
  computed: {
    fooCount () {
      return this.$store.state.foo.count;
    },
  },
  serverPrefetch () {
    this.registerFoo()
    return this.fooInc()
  },
  mounted () {
    this.registerFoo()
  },
  destroyed () {
    this.$store.unregisterModule('foo')
  },
  methods: {
    registerFoo () {
      this.$store.registerModule('foo', fooStoreModule, { preserveState: true })
    },
  },
}

Given that we have a route componet Fruit with path '/fruits/:id'. At the first time we visit the page '/fruits/1', during server-side rendering, store module 'foo' will be registered and the final global state will be injected into HTML as window.__INITIAL__STATE, once client app start hydrating, client app's state will be replaced by window.__INITIAL__STATE, after entering the route /fruits/:id, module 'foo' will be registered as expected and keeps previous state not changed. So far, that's all ok (except this problem #239 i'v found before). But once you leave this route, destroyed hook will be called and module 'foo' will be unregistered. Then we click history back button, we'll back to this route and since module 'foo' has not been registered yet, computed property fooCount will cause an TypeError because this.$store.state.foo is undefined.
Oops...That's not the biggest problem! The worst thing is that after mounted hook called and this.registerFoo() called, the 'foo' module will still be registered with option { preserveState: true } and as a result this.$store.state.foo will always be undefined (previous state has no property 'foo' due to unregistration).
That's the problem.

Here follows my solution: no duplicated module registration and no unregistration, then everything will be ok.

{
    computed: {
      fooCount () {
        return this.$store.state.foo.count;
      },
    },
    methods: {
      registerFoo(preserve = false) {
        if (!this.$store._modules.root._children['foo']) {
          this.$store.registerModule('foo', storeModuleFoo, { preserveState: preserve });
        }
      },
    },
    serverPrefetch() {
      this.registerFoo();

      return this.fooInc();
    },
    mounted() {
      this.registerFoo(true);
    },
  }

I'm not sure is this solution valid, please give your advice if anything went wrong, thanks all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions