Help us understand the problem. What is going on with this article?

VuexですべてのStateを初期化する

はじめに

ログアウトをしてもStateに値が残っているため、別のユーザでログインした際に前回の情報を参照できてしまうという問題の対策です。

"vuex": "3.1.1"

やりかた

各モジュールにStateを初期化するAction、Mutationを作成しておくのが定番らしいのですが、面倒なので以下の関数を定義しておきます。

const RESET_STATE = 'RESET_STATE'

function createResetHandler(module: any, name: string) {
  const childModules = module.modules
  if (childModules) {
    for (const key of Object.keys(childModules)) {
      createResetHandler(childModules[key], `${name}/${key}`)
    }
  }

  // stateがないmoduleは初期化の必要がないので無視
  if (!module.state) {
    return
  }

  // NB: stateは関数で定義しておく
  if (typeof module.state !== 'function') {
    console.error(`Vuex module state of '${name}' is not a function`)
  }

  module.mutations = module.mutations || {}
  module.actions = module.actions || {}

  const mutation = (state: any) => {
    Object.assign(state, module.state())
  }
  module.mutations[RESET_STATE] = mutation

  // グローバルにアクションを定義する
  const action = {
    root: true,
    async handler(context: { commit: Function }) {
      context.commit(RESET_STATE)
    },
  }
  module.actions[RESET_STATE] = action
}

これをStoreを作成する前に実行しておく

const modules = {
  module1,
  module2,
  ...
}

for (const key of Object.keys(modules)) {
  createResetHandler(modules[key], key)
}
new Store<State>({ state, mutations, actions, modules })

リセットするとき

logout({ dispatch }) {
  // --- ログアウト処理 ---
  dispatch(RESET_STATE, undefined, { root: true })
}

解説

stateを関数にしておくことでmodule.state()を実行すると初期値が返されます。

_actions = { RESET_STATE: [ function, function, function ... ] }というようにStoreにアクションが登録されているので、dispacth(RESET_STATE, undefined, { root: true })ですべてのアクションが呼び出されます。

まとめ

RESET_STATEに引数を渡せるようにして、特定のモジュールのみ初期化するということもできます。
けっこう重い処理なので使い所は要注意です。

参考

https://github.com/vuejs/vuex/issues/1118#issuecomment-439471054

FuJino
iOSやってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away