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

VuexのMutationとActionの切り分け

More than 1 year has passed since last update.

Vuexを勉強してたらMutationとActionで処理の切り分けをどうしようか、というところで悩んだので自分なりの考えを書きます。

MutationとActionの違い

そもそもMutationは同期処理でなければならなず、Actionは非同期処理も可能という違いがあります。
これは、Mutationで複数の状態の変更が非同期に行われた場合に挙動が予測不能になるのを防ぐという意図があるようです。
Actionでは、Mutationに対してcommitを行うことで間接的に状態を変更しますが、Actionを呼び出すためのdispatchメソッドはPromiseを返すため、処理の順序を制御することが可能になります。

同期処理はどっちに書く?

非同期処理はActionに書かなければないですが、同期処理はどちらに書くべきか?
ここで、Actionに渡されたtextが"Yes"ならcount+1、"No"ならcount-1、それ以外はそのままというStateについて考えてみます。

new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        plus (state, num) {
            state.count += num;
        },
    },
    actions: {
        vote (context, text) {
            if (text === 'Yes') {
                context.commit('plus', 1);
            } else if (text === 'No') {
                context.commit('plus', -1);
            }
        },
    },
}

このように、MutationはStateの変更にとどめておき、Actionで処理を行うというようにしたほうが各処理の責務が明確になっていい気がする。
(そもそも、文字列の条件分岐はComponentのほうでやったほうがいいんじゃないの、というのは置いといて)

でも、その変更処理がstateの状態に依存する変更ならMutationで処理を行いたい。
例えば、0~9までカウントアップして、9の次はまた0に戻るような処理を書く場合。

new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        countup (state, num) {
            state.count = (state.count + num) % 10;
        },
    },
    actions: {
        increment (context) {
            context.commit('countup', 1);
        },
    },
}

できるだけ、stateを直接参照するのもMutationの内側に閉じ込めてしまいたい。

Componentから直接commit

Vuexでは公式でComponentからMutationを直接commitすることを許可しています。

image.png
ただ、この図にはComponentから直接commitするルートがないんですよね。
もともとはたぶん図のほうで、Componentからの操作はActionに限定させたいという思想があったのだと思います。
ただ、それだと単純な状態の操作を作るときにコードが冗長になる(commitするだけのActionが乱立する)ので、これが許可されたのではないかと思います。
なので、できるだけAction経由で呼び出したほうがいいのではないかと思います。

mutation-types.js

Componentに対して公開するのをActionに限定するという考えを進めていくと、mutation-types.js(Mutationのタイプを定数化して外出しにするためのjs)は、action-types.jsにしたほうがよいのではないかと思えてきます。
もちろん、commitもdispatchも文字列で呼び出すことからMutationのタイプも定数で定義したほうがいいと思いますが、外に出すのはActionのほうではないかと。

結論

あくまで個人的な意見ですが

  • Mutationは状態の変更のみを行う(privateな(Actionだけから呼ばれる)セッター)
  • Actionは処理の公開や複雑な処理を行う(publicなメソッド)

というイメージです。
どうもJavaの考えに引きずられてる感じはありますね。

参考

Vuex 公式

frost_star
まだまだ半人前プログラマー。
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした