[elm-spa v6] Shared Stateですべてのページに必要な状態を管理する
elm-spaは、ElmでSPAをするためのボイラプレートを生成してくれる、とても便利なツールです。バージョン6で仕様が変わった部分があるので、変更箇所をお伝えする記事です。今回はすべてのページで必要な状態を管理するShared State について解説したいと思います。今回の知識を発展させるとelm-spa v6でユーザ認証実装
で書いたように認証機構も作れるので、よければ合わせて御覧ください。
今回のサンプルは、時刻・カレンダー表示とパソコンのタイムゾーンに合わせる設定画面の3画面の遷移ができるSPAです。初期状態ではタイムゾーンはUTCとなっており、以下のデモでは最初の時点で、PCの時刻とズレが生じています。設定画面でタイムゾーンを設定した場合、画面遷移をしてもタイムゾーンがJSTとして計算がされるようになります。
デモのコードはこちら
デモコードを解説
デモコードを解説していこうと思います。ソースコードはPages
ディレクトリと直下のShared.elm
に分かれます。Pagesはそのまま時刻・日付・設定画面の3つに対応しています。Shared.elm
がShared Stateを管理するファイルになります。
src
├── Pages
│ ├── Calendar.elm
│ ├── Home_.elm
│ └── Settings.elm
└── Shared.elm
時刻表示画面(Home_.elm)
Model
には、時間を保存するための変数timeMaybe
を定義し、init
では、時間取得のためのCmdを発行します。
update
では、時間を保存します。
時間を表示をしたり、elm-spaが自動生成したGen.Route
モジュールを使ってリンクを生成したりしています。時間を表示するときにModel
ではなく、Shared.Model
からタイムゾーンを参照しているのがポイントとなります。このShared.Model
はどこから来たのでしょうか?
答えは、page
関数が一般的なElmファイルで言うmain関数の役割に対応していて、Shared.Model
をinit
, update
, view
, subscriptions
関数に任意に渡すことができます。例えば、initに渡してModel
として設定することもできます。状況によって使い分けてください。
日付表示画面(Calendar.elm)
基本的には、時刻表示画面と代わりがありません。
タイムゾーン設定画面(Settings.elm)
時刻と日付の表示画面は、Shared Stateを使う画面でした。設定画面はその逆でShared Stateを変更する画面です。変更が必要なページはPage.element
ではなく、Page.advanced
である必要があります。
advancedの場合、Cmd msgではなく、Shared SatateのCmdとPageのCmd msgの2つをマージして抽象化した、Effect
という型になります。
PageのCmdをEffectにするには、Effect.fromCmd
関数。SharedのMsgをEffectにするには、Effect.fromShared
関数でそれぞれ変換する必要があります。
viewは基本的なページと変わり有りません。
Shared.elm
Sharedは基本的にviewがない(用意しても構いません)Elmファイルのようなものです。タイムゾーンを持ち、updateで更新します。
Msgは外から使えるように、中身もexposeします。
注意点
今回は、Shared State
を使う画面と変更する画面で分かれていましたが、もし使うと変更が同じ画面の場合には注意が必要です。Shared State
がその画面中で変わったとしてもそのPageのviewには即時反映されません。なぜなら、Msg
, update
, Model
が別物だからです。そのため、もし変更を追従したい場合には、initでShared.Model
をModel
へセットして、Shared State
の変更と共にModelの変更も行うと良いでしょう。
init shared =
{ timezone = shared.timezone
}
update msg model =
case msg of
ChangeShared current ->
({ model | timezone = current }, Effect.fromShared <| ChangeTimezone current )
view model = -- Shared.Modelは使わない
p [] [ text <| calc model.timezone ]
まとめ
elm-spaはとても便利なツールですが、一つ一つの特性を理解して使わなければ真価を発揮できません。うまく利用して、SPAを便利に作りましょう。
Discussion