対象読者
- JavaScriptとWeb開発の基礎に理解がある方
- Reactを用いたJavaScriptアプリケーション開発の経験者
前提環境
筆者の検証環境は以下の通りです。
- macOS Monterey 12.3.1
- Node.js 18.2.0/npm 8.9.0
- React 18.1.0
- react-scripts 5.0.1
- xstate 4.32.1
- @xstate/react 3.0.0
状態管理とステートマシン
どんな操作をすると、アプリケーションの状態(内部データ)はどのように変化するのか。ある操作をした次に、どんな操作が許されるのか。大きなアプリケーションになるほど、状態の管理は複雑になります。また、状態を監視・変更するコードはアプリケーション内に分散して配置されてしまうことが多く、改修の際に既存のソースコードを読解するための難易度を上げる一因となっています。
状態を上手に整理・管理する手法があればよさそうです。幸い、状態管理というテーマはソフトウェア開発の世界でも古くから存在するので、多くの先人たちが関心を持ち、管理のための手法を考案してくれており、そのひとつに、状態の遷移を数学的に抽象化した「ステートマシン(有限オートマトン、有限状態機械とも呼ぶ)」というモデルがあります。
ステートマシンは、次のような特徴を持った概念です。
- ある粒度のシステムについて有限個の「状態」があると定義する
- ある時点ではシステムはある一つの状態になり、これを「現在状態」と呼ぶ
- ある状態はなんらかのきっかけにより別の状態へと移行し、これを「遷移」と呼ぶ
文章だけだとわかりづらいですね。ですが、ご安心ください。ステートマシンをわかりやすく記述するための表現手法として「状態遷移図」というものがあります(図1)。
丸で描かれているのが「状態」で、矢印で描かれているのが「遷移」です。基本的にはある状態から別の状態に遷移しますが、「お金を投入する」のように自身へと遷移する場合もあります。
まだ何もしていないのが「初期状態」です。そこから「お金を投入する」という行動をすると、それがきっかけとなって状態が遷移し、「お金を投入中」という状態になります。ここからさらにお金を投入することができますが、商品の最低金額を超えた時点で「商品を購入できる」という状態に遷移します。ここでようやく「商品を購入する」という行動が取れるようになりました。商品を購入して、まだ投入金額の残高があれば引き続き商品を購入できますが、もし残高が足りなくなっていれば「お金を投入中」の状態へと遷移します。
実物の自動販売機よりもかなり簡略化したモデルなので、お釣りレバーを引いた結果として残高がなくなった場合の挙動などはサポートしていませんが、雰囲気は掴めるのではないでしょうか。
さて、図1の状態遷移図によって表現されたステートマシンをアプリケーションに落とし込むとしたら、読者の皆さんはどんなコードを書くでしょうか。投入金額が増えるたびにif文で金額をチェックして、各商品の購入ボタンを有効にしたり無効にしたりするでしょうか。それもよいのですが、やはり状態遷移図の形でまとめたステートマシンはわかりやすいので、そのままプログラムに落とし込めると嬉しいですよね。それを実現してくれるのが、XStateというライブラリです。
XStateとは
XStateはステートマシンや状態遷移図をJavaScriptで扱うためのライブラリです。
XStateの特長としては、状態遷移図のXML表現としてW3Cで研究されているSCXMLを遵守したデータ構造で内部データの管理を行っていることが挙げられます。専門家が十分に研究・議論した仕様に沿ってライブラリを作ることで、複雑なステートマシンも表現できるはずである、と公式ドキュメントで謳っています。
APIはxstate
パッケージの createMachine
関数を使ってステートマシンを定義し、それを他のライブラリから扱うことになります。Reactの場合は @xstate/react
から扱うことでReact Hooks経由でステートマシンを操作できるので、ReduxやuseReducerと似た操作感になります。
ビジュアライザーで状態遷移図を確認しながらステートマシンを作る
さて、簡単なステートマシンの作り方を解説していきますが、ちゃんと実装できているのかどうかを確認する方法がないと不安ですよね。実は、XStateには公式のビジュアライザーが提供されており、制作中のステートマシンが意図した状態遷移図になっているかどうかを確認しながら実装を進めることができます(図3)。
右ペインのエディタにステートマシンの定義を実装すると、左ペインに状態遷移図としてビジュアライズされる仕組みです。左ペインの四角い黒い枠が状態、水色やグレーの角丸四角が遷移です。このビジュアライザーでは実際に遷移をクリックしながら状態を変化させることもできます。自分でGUIを実装することなく、マウスクリックで状態遷移がうまく組み上がっているかを動作確認できるのは、なかなか良い体験です。このビジュアライザーの存在が、XStateの大きな魅力になっています。