Vue で vuex do not mutate vuex store state outside mutation エラーの解決方法

VuexState

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、Vue で vuex do not mutate vuex store state outside mutation エラーの解決方法について解説していきます。

vuex do not mutate vuex store state outside mutation エラーの解決方法

vuex do not mutate vuex store state outside mutation エラーとは?

このエラーは、Vuex の Store で管理している State を Mutaition を使用せずに変更した場合に発生するエラーです。

そして、これは、JavaScriptの Copyや、メモリ管理がわかっていないとハマるエラーになります。

どういうことか、1つずつ順に説明していきます。

JavaScriptには、Shallow Copy(浅いコピー)とDeep Copy(深いコピー)がある

まず、知ってもらいたいことは、JavaScriptには、Shallow Copy(浅いコピー)と Deep Copy(深いコピー)があるということです。

この2つの Copyの違いは、Copyしている Objectなどの Dataの参照先のメモリにあります。

Shallow Copyの場合は、Copy元とCopy先のDataが、同じメモリを参照 (メモリ共有)しています。

つまり、同じメモリを参照しているので、どちらかを変えると、もう一方も変わってしまう状態になっています。

それに対して、Deep Copyの場合は、Copy元とCopy先のDataの参照先は別になっているので、

どちらかを変えても、もう一方に影響はありません。

以前に、JavaScriptで再帰的にDeep Copyする方法をまとめているので、こちらの記事も見てみてください。

解決方法: Store で Deep Copyした Dataを渡すように getters を設定する

そして、今回の Vue の Vuex のエラー内容 (vuex do not mutate vuex store state outside mutation) は、

先ほど説明した Shallow Copy(浅いコピー) によるメモリ共有によって、発生するパターンが多いです。

つまり、Vuex の Store の Stateを使用する Vue Component で、

Shallow Copy(浅いコピー) の状態で、Stateを使ったDataを変更しようとすると、

Store の State本体も変更されてしまうため「Mutationを使用せず Stateを変更するな」とエラーになるわけです。

このエラーの対応方法・解決方法として、おすすめなのは、

Store で Deep Copyした Dataを渡すように getters を設定することです。

getters を通して、Stateを取得するようにルールを統一しておき、その gettersで、Deep Copyの処理をしておけば、このようなエラーは避けられます。

// 1. Store_State で、Globalに管理したい Dataを管理する
export const state = () => ({
  // 1-1. UserData_Object
  user: {},
  // 1-2. CartItemList
  cartItemList: [],
});

// 2. Gettersから、Vue_Component たちは、Stateを受け取る
export const getters = {
  // 2-1. Vue_Component に Dataを渡す、 Getters で、DeepCopyした Dataを渡す
  // Deep_Copy: JSON.parse(JSON.stringify(states.TargetData))
  user: (states) => JSON.parse(JSON.stringify(states.user)),
  cartItemList: (states) => JSON.parse(JSON.stringify(states.cartItemList)),
};

// 3. Mutation で、Store_State を Updateする
export const mutations = {
  setUser: (states, user) => (states.user = user),
  setCartItemList: (states, itemList) => (states.cartItemList = itemList),
};

JavaScript書籍 Ver. 中級-上級者向け

JavaScript書籍 Ver. 初級者向け

Twitterやってます!Follow Me!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

最近の投稿