2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Xstate で基本的なステートマシンを作成する

Posted at

状態とその遷移が予め大体決まっている場合、Xstate のEditor を利用すると視覚的にも分かりやすくステートマシンが作れます。今回はEditor の使い方と、各状態と遷移、Context 、Action 、invoke について記載したいと思います。

xstate Editor の使い方

状態の作成と遷移方法

image.png
firstState からNEXT が呼ばれた場合はsecondState へ、CANCEL が呼ばれた場合はthirdState に遷移します。

Action

image.png
ここでは遷移にAction がついています。Action は状態につけることもできます。この場合は、secontState 状態に入ったときに指定のsetParameter が実行されます。Action はただ実行されるものなので、分岐等はありません。Context にデータをセットする動作や、クリーンアップ動作で利用しました。

image.png

Invoke

image.png
invoke は状態につけることができます。invoke ではreject とresolve で渡す先を選び、done の場合とerror の場合で異なる遷移先を指定することができます。バリデーションチェックや、エラー処理が必要な動作はinvoke を使っていました。

コード実装

Xstate のEditor からコードに落とすことができます。今回は一例として少しコードを紹介します。

image.png

今回のこのコードでは、Editor からコードを起こすと以下のようになります。Action やService は別のところに記載します。Context はparameter のみを持つようにしています。

import { createMachine } from "xstate";

interface machineContext {
  parameter: boolean | undefined,
}

const machine = createMachine<machineContext>({
  context: {
    parameter: undefined,
  },
  id: "stateMachine",
  initial: "firstState",
  states: {
    firstState: {
      on: {
        NEXT: {
          target: "secondState",
        },
        CANCEL: {
          target: "thirdState",
          actions: {
            type: "cleanUp",
          },
        },
      },
    },
    secondState: {
      entry: {
        type: "setParameter",
      },
    },
    thirdState: {
      invoke: {
        onDone: {
          target: "success",
        },
        onError: {
          target: "error",
        },
        src: "ValidationCheck",
      },
    },
    success: {},
    error: {},
  },
});

コンポーネント内で使う際は、UseMachine を利用します。

const [ state, send ] = useMachine(machine, {
    actions: {
      cleanUp: (_, event) => {
       // 実装
        });
      },
      setPrameter: assign({ parameter: (_context, event) => event.data.parameter }),
    },
    services: {
      ValidationCheck: (context, _event) => {
        return new Promise((resolve, reject) => {
        // resolve ならDone 遷移、reject ならError 遷移
          }
        });
      },
    },
  });

ここでAction とInvoke のService を設定します。遷移を呼ぶ際は以下のように書きます。

send({ type: 'NEXT', data: { parameter } })

parameterの中には入れたいデータが入ります。これて、NEXT が呼ばれ、setParameter でContext に値がセットされます。Service の中でContext に値を渡すこともできます。resolve (あるいはreject )で以下のように記載します。

resolve({ data: parameter });
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?