getter, mutation において state を最初から分割代入してしまう

state 全てを取得するよりも、関連するプロパティのみに制限した方が可読性は高い。もちろん、複数のプロパティを横断する際にも、必要なプロパティだけを分割代入すればいい。

store.js
// const getters = {
//   appNumber(state) {
//     return state.appNumber;
//   }
// };

// state を最初から分割代入してしまう
const getters = {
  appNumber({ appNumber }) {
    return appNumber;
  }
};

メソッド持ちインスタンスを store に入れないために

(この運用が最適なのかは議論の余地があるとして)モデルからインスタンスを作成し、これに validation や値の演算をそのメソッドによってさせる場合、これを store に入れてしまうと、特に store の localstrage への永続化/復元の際、正常に動作しない。

Store に入れれないとすればどうすればいいか。以下のような実装が可能である。

  • インスタンス化はコンポーネントの UI 内部でのみ行う。例えばゲッターで取得した値を使ってインスタンスを生成する。
  • setState する場合には、action でインスタンスを投げ、mutation する前に値のバリデーションをしたのち、値のみを state にセットする。
  • private な変数は _ を接頭語に使う。
  • getter/setter をセットで定義すること。
  • public な isValid というメソッドから、private な _isValid とといったメソッドを参照して実行する。つまり isValid というインターフェイスを用意すること。
model を store に入れない
// モデル用クラスの定義
export class SomeValue {
  private _value: number; 
  private static _instance: SomeValue; // 一度内部にインスタンスがあればこれを返せばいい
  private constructor() {} // new は基本しない

  // インスタンスを作成して返す。constructor 的な機能
  static getInstance(): SomeValue {
    if (!SomeValue._instance) {
      SomeValue._instance = new SomeValue();
    }
    return SomeValue._instance;
  }

  // getter/setter は対になるように

  // getter
  get value(): number {
    return this._value;
  }

  // setter
  set value(value: number) {
    this._value = value;
  }

  private _isValid(): boolean {
    return this._value > 0 && this._value < 100;
  }

  public isValid(): boolean {
    return this._isValid();
  }
}

// モデルを使う
const someValue = SomeValue.getInstance(); // インスタンスを作成
someValue.value = value; // 値を入れる
if (!timeValue.isValid()) {
  // エラー処理
} else {
  // 正規の処理前に必要な処理
}
this.setValue(timeValue); // 正規な処理, action or mutaiton を実行

// mutaion の処理
setValue(state, value) {
  if (value.isValid()) { // validation
    // インスタンスそのものではなく、インスタンス内の値のみをセットする
    state.value = value.value;
  } 
  else {
    // エラー処理
  }
}