Vuex のルールと Component 設計

こんにちは、自意識過剰な正義のヒーローでお馴染みの株式会社SCOUTERの石岡 将明( @masaakikunsan )です。

前回の Flutter のブログで、「2月半ばにAPIの叩き方やページ内のレイアウト作り方などをちゃんと解説したブログを書こうと思うのでお楽しみに!」と言ったのですが、あれ以降 Flutter を触れていないので今回は普段触ってる技術について書きます。

techblog.scouter.co.jp

現在 SCOUTER では、SARDINE と back check の大きく分けて2つの開発チームで開発を行っています。 僕は、back check で プレイングマネージャーとして開発をしているのですが、SARDINE チームに最近フロントエンドの相談を受けるようになってきたので今回はその話をしていきます。

Vuex でのルール

Vue や Nuxt で開発している場合状態管理に Vuex を使っているかと思います。 なので、今回は Vuex の概念や書き方については省略し僕が開発するときのルールを紹介します。

namespaced を true にしよう

namespaced を true にすることで、モジュールごとに自動的に名前空間が付与されます。 これがないと、複数のモジュールが同じミューテーション/アクションタイプに反応することができてしまい大きくなったときに破綻してしまうでしょう。

Nuxt で開発をしている場合、モジュールモードが上記の namespaced=true になります。

ja.nuxtjs.org

mapState を使わない

Vuex には mapGetters ヘルパーが存在します。 mapGetters はゲッターの評価後の値を返すコンポーネントの computed オプションを作成します。 Vuex の state を使いたい時に filter したりやなんらか変更したいというモチベーションは結構あると思います。 そのような理由から getters では state を加工しないデータも全て乗せ mapGetters で統一するとわかりやすくなって良いでしょう。

mapMutations を使わない

state を変更する唯一の方法はミューテーションです。 なのでコンポーネント内で直接 mapMutations を使ってミューテーションをコミットする方が結構いますが、 actions でミューテーションをコミットするのが良いでしょう。 そうすることでコンポーネント内で mapActions ヘルパーを使うだけでよくなりわかりやすくなりますし、管理が楽になります。

厳格モードにしよう

普通にルールにしたがってやってたらこれは本来しなくていいのですが、結構いろんなプロジェクトで state をミューテーションハンドラの外部で変更してるコードを見ます。 なのであらかじめ厳格モードにしミューテーションハンドラ外部で state を変更できないようにしましょう。

Nuxt で開発している場合デフォルトで厳格モードになっているので特に設定などはいりません。

ja.nuxtjs.org

state を全て Vuex に逃すのをやめよう

結構 Redux を書いている人は state を全て Vuex に逃しているのですがこれは store が肥大化したり助長でまわりくどくなりいいことはありません。 状態がコンポーネント内で完結するのであればそれはローカルステートに持たせましょう。

モジュールの切り方

以前はページ毎 Vuex のファイルを作成していたのですが、そうすると複数ページで共通する state がでてきて困りました。 今はドメインごとにファイルを作成するようにしています。 そうすることで、違うモジュールの state をいじる必要性は基本的にないでしょう。

以上が僕が Vuex を書く上でのルールです。 次に Component の設計について書いていきます。

Component の設計

Component を設計する上でよく耳にするのが「再利用性の高い」です。 僕は、Component を設計する上で再利用性はあまり考えないようにしてます。 まずはじめにその理由について書きます。

再利用性の高いコンポーネント

再利用性の高いコンポーネントを作る上で、3つのことが必要だと僕は思っています。

  1. 実装者の能力
  2. デザイナーの能力
  3. 時間

1に関しては言わずもがなだとは思いますが、実装者の能力がない場合依存性が高かったり等再利用性のあまり高くないコンポーネントになってしまうことが多いでしょう。

2は以外と頭にない人が多いのですが、これも大事です。 デザイナーはコンポーネント志向をまず理解している必要があります。次に過去・未来を考え再利用性ができるものは再利用ができるように設計しデザインをしなければいけません。

デザイナーが実装もできる人間であればこれらは当然頭にあると思うので問題ないと思うのですが、必ずしも上記をデザイナーができる必要があるわけではありません。 エンジニアと協業し、しっかりとコミュニケーションをとりやれば上記を満たすデザインができるでしょう。

3の時間は当たり前だろとは思うと思うのですが、口で言うほど再利用性の高いコンポーネントは簡単には作れないので思ってる以上に時間はかかるよという話です。 再利用性の高いコンポーネントを作る上で、コンポーネントの粒度・ロジックのシンプルさ等色々と考えることがあります。 なので時間はかかるものと考えるのが良いでしょう。

再利用性の高いコンポーネントを作る難しさはここまででわかっていただけたと思います。 本題の再利用性をあまり考えなくていいと考えている理由ですが、大きい理由としてはどうせ使わないというのがあります。

プロダクト開発をしている人であれば、割と経験あると思うのですが、再利用性を考えてコンポーネントを作り込んだは良いがその後デザインで使われることがなかってのはざらにあります。 そういうことを考えると再利用性の高いコンポーネントを作る難しさとコストを考えるとあまり再利用性はあまり意識しないほうが良い意思決定でしょう。

僕は2回から3回同じデザインがでてきたら切り離しコンポーネント化するようにしています。

次にコンポーネントを作るときに考えることを書いていきます。

コンポーネントを作る上で考えていること

僕は、コンポーネント作る上で以下3つを意識しています。

  1. コンポーネントの役割を考える
  2. 依存を少なくする
  3. なるべく状態を持たないようにする

コンポーネントの役割を考える

コンポーネント志向で開発をしている場合 Presentational Component と Container Component を耳にしたことあると思います。 基本的にコンポーネントはこの分類で考えましょう。

Presentational Component とは、View に特化したコンポーネントで、自身では状態は持ちません。 Presentational Component では、コンポーネントに閉じた状態を除き状態を持たず、props で渡ってきたデータを表示するようにします。

Container Component とは、Presentational Component にデータを渡したり、機能をもたせたりと子コンポーネントの振る舞いを定義していきます。

この2つで大枠分類して進めると状態管理とかでも悩んだり基本的にしないでしょう。 ただ例外も存在するとは思うのでその都度チームで話しあいルールを決めると良いかとおもいます。

Nuxt で開発する場合、僕は基本的にpages に Container の役割をもたせています。 コンポーネントに閉じていない状態やロジックや Vuex による操作は全て pages で行うようにしており、そうすることで pages からコンポーネントへ上から下に流れるようなイメージで開発が進められて良いです。 ただ、pages が肥大化する場合もあるのでそのような場合は Container Component を作成し、pages と Presentational Component の間に挟んでいます。

依存を少なくする

これは、再利用性にも関わってくる話です。 依存が大きいと再利用性もしずらくある一定の場所でしか使えなくなってしまうデメリットがあります。 そして依存が大きいコードはレビュアーのコストも上がります。 依存している箇所のコードを読みしっかりと理解していないと正しいレビューができないデメリットがあります。

なので、再利用性は考えなくてもいいですが、なるべく依存は少なくしましょう。 そうすることで、修正なども用意に行えます。

なるべく状態を持たないようにする

状態を持つということはそれだけでその状態に振り回される為依存が大きいということです。 状態をもたせるかどうか責務で考え、状態をもって良いか良くないかをしっかりと考えましょう。 ここまでを踏まえて考えれば状態を持つべきかどうかはわかるかと思います。

コンポーネントを作成する時は、しっかりとそのコンポーネントの責務などを考えて粒度やデータの持ち方を考えて作成しましょう。

さいごに

Vuex のルールや Componentの設計について書きましたがいかがだったでしょうか? 他にも考えていることはあると思うのですが、言語化できていないので今回はこれぐらいにしようかと思います。 状態管理やコンポーネントの設計は トライ&エラーを繰り返していくしか身につける方法はないと僕は考えています。 なので、いっぱい失敗して自分なりのルールを見つけられるようになりましょう。 この記事がどこかで役に立つと幸いです。

現在、back check チームでは、エンジニアの募集をしております。 僕と一緒にフロントエンドを朝まで語り尽くしたいフロントエンドエンジニアやレベルの高いフロントエンドチームと最高のプロダクトを作って行きたいサーバーサイドエンジニアは是非ご応募お願いいたいします!

www.wantedly.com

www.wantedly.com