こんにちは、丸山です。
前回フロントエンドの状態管理を考える一つの方法としてFluxを見てみました。 今回はThe Elm Architectureについて見ていきたいと思います。
The Elm Architectureとは
公式ガイドによればThe Elm Architectureは関数型プログラミング言語であるElmでアプリケーションを構築する際に使われるパターンで、 モジュール性やコードの再利用性、テストのしやすさなどに優れているということです。 Fluxの時と同じように、まずThe Elm Architectureの要素を見ていきます。
Model
アプリケーションの状態
Update
状態を更新する方法
View
HTMLとして状態を閲覧する方法
The Elm Architectureは以上の3つの要素から構成されます。
次に実際にコードを見て、これらがどう使われているのかを見ていきます。
The Elm Architectureのデータフロー
こちらはElmで書いたカウンターアプリのコードです(公式ガイドにあるサンプルコードを少し書き換えました)。
import Browser
import Html exposing (Html, text, p, div, button, form, input)
import Html.Events exposing (onClick, onInput)
import Html.Attributes exposing (value)
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model = Int
init : Model
init = 0
-- UPDATE
type Msg = Increment Int | Decrement Int
update : Msg -> Model -> Model
update msg model =
case msg of
Increment n ->
model + n
Decrement n ->
model - n
-- VIEW
view : Model -> Html Msg
view model =
div []
[ div [] [ text (String.fromInt model) ]
, button [ onClick (Increment 1) ] [ text "+1" ]
, button [ onClick (Increment 10) ] [ text "+10" ]
, button [ onClick (Decrement 1) ] [ text "-1" ]
, button [ onClick (Decrement 10) ] [ text "-10" ]
]
ボタンを押すことで、そのラベルに書かれた計算が行われ結果が表示されます。

データフローを追う前にまずは各要素を見ていきます。 Elmの仕様の詳細については省略しますが、できるだけ何をやっているのかわかるように説明したいと思います。
Model
type alias Model = Int
この部分がこのアプリケーションの状態になります。
Modelという型を定義しています(Int型にModelという別名を付けただけのものです)。
カウンターアプリにおける状態なので、計算された結果が格納されます。
Update
Updateには状態を更新する方法の定義とその内容が書いてあります。
type Msg = Increment Int | Decrement Int
ここでは状態を更新する方法の種類と更新に使われる値の定義をしています。 Int型の値を使ってIncrementを行う、またはInt型の値を使ってDecrementを行うといった意味になります。 FluxでいうところのActionのようなものです。
続く、
update : Msg -> Model -> Model update msg model = ...
の部分で、実際にどうやって状態を更新するのかを書いています。
case msg of
Increment n ->
model + n
Decrement n ->
model - n
この部分でメッセージがIncrementならModelに値(先ほどMsgのところでIntで定義した部分です)を足し、Decrementなら引くといったことをやっています。
View
Viewの部分ではModelを受け取り、HTMLを通して表示をしています。
div [] [ text (String.fromInt model) ]
またボタンをクリックすることでメッセージを発行するという定義もされています。
button [ onClick (Increment 1) ] [ text "+1" ]
この部分では、"+1"ボタンをクリックすることで Increment 1というメッセージが発行されるという動作を表しています。
最後にデータの流れを見ていきます。
例:"+1"ボタンがクリックされた場合
ViewからメッセージIncrement 1が発行される

Updateでメッセージを受け取り、その内容を見て状態の更新(Modelに対して+1)を行う

更新された状態がViewに渡され、計算された結果が表示される

終わりに
前回のFlux、今回のThe Elm Architectureと見てきましたが、Fluxでは状態と更新処理の管理はstoreで、The Elm ArchitectureではそれぞれをModelとUpdateが担っていましたが、どちらも決まった場所に置かれれていることは同じでした。
またFlux、The Elm Architecture共に流れは単一方向となっていたことがわかりました。
両者に共通する部分をまとめると、
- データの流れがシンプル(単一方向)
- データの取得・更新の流れの見通しがよくなる
- 状態の管理と更新処理が特定の箇所にまとまっている
- 管理や再利用がしやすくなる
が挙げられます。
この辺りが、状態管理における一つのパターンになるのではないかと思います。