前書き
業務でNuxt.jsアプリの改修をしていて、
なんかバグ出てるやん
→ どうやらStoreの値中の配列の値がおかしいぞ
→ 変な値がcommitされているんだな
→ commit値は正常だな・・
→ あ、変なところでまたcommitが呼ばれちゃってるんだな!
→ commitは(正常時の)1回しかされていないぞ・・
→ 詰
なことがあったので、これを解決した時の話を書いてみます。
体験談
今回のポイントは、異常値を示した値の型が配列
と言う点。
最初はVue初級者が故に、
storeの値はcommitから以外で変わり得ない
、と言う前提はあったため、
VueXの仕様的に誤った使い方しているんじゃ、、と的外れなあたりをつけてVue周りを調べてました。
そんな時、ふと配列で思い出したのが、
配列は参照型やん
、です。
なので、storeから取り出した配列を直接いじってる部分がないか
と言う方針で調査を進めました。
そして見つけました。
lodash(JSライブラリ)の_.remove()
メソッド
※removeメソッドについてはこちらの記事がとても参考になります。
この処理の前後のstoreの値を確認し、確信しました。
この処理周りを改善し、無事バグ解決。
参照型とは
超ざっくり言うと、値が置いてある場所、のこと。
Java習いたてでよく注意点として出て来ます。
ありがちな事象は以下
↓
ある変数を別の変数にコピーして、値2個できたやん、とか思って片方を変更する。
でも参照型の場合は実際には場所を指しているので、コピーされたのは場所情報だけ、変更されたのはその場所にある値である。
つまり同じ場所を指しているもう一方の変数も、一緒に値が変わってしまう。
文面で起こすの辛いので実例↓
// JSの場合
var a = [1,2,3,4,5]; // 配列定義。
var b = a; // 変数をコピー。実際は配列のある場所だけコピーされる。
b.pop(); // bの末尾削除
console.log(a); // [1,2,3,4]
console.log(b); // [1,2,3,4]
// aも削除されちゃった
まとめ
配列が参照型、と言うのは実際にその類のバグに遭遇しないと意識しないと思うので、
体験談を書き記してみました。
これがあってから改めて意識するようになったのが、
- Vuexのstoreの中身がcommit以外から変更されるパターンもある(ReactのReduxなどでも同様だと思う)
- storeなど固定値として保持されている配列を直接いじらない
- 配列の中身に関するバグがあったら、直接操作を行っていないかを疑う
です。
ちなみにどうしてもいじる必要がある場合は、
例えばlodashの_.cloneDeep()
と言うメソッドを使うことで、
配列を完全複製し、それを使用する方法などが回避策になるかなと思います。
この記事を見て、
うわ、こんなバグもありえるのか!、と感心していただけたり、
自分もあったわw、と共感していただける人がいたら幸いです。