XState > 親・子・兄弟Machine間での通信
Table of Content
XState > 親・子・兄弟Machine間での通信
親と子、親を通じて子から子へ伝える方法のメモ
https://xstate.js.org/docs/guides/communication.html#invoking-machines
first
子マシン1号
import { createMachine, sendParent } from "xstate";
export const childMachine1 = createMachine({
id: "remote",
initial: "offline",
states: {
offline: {
on: {
WAKE: "online"
}
},
online: {
after: {
1000: {
actions: sendParent("CHILD1.COMPLETE")
}
}
}
}
});
子マシン2号
import { createMachine, sendParent } from "xstate";
export const childMachine2 = createMachine({
id: "remote2",
initial: "offline",
states: {
offline: {
on: {
WAKE: "online"
}
},
online: {
actions: sendParent("CHILD2.COMPLETE", {
delay: 2000
})
}
}
});
親マシン
entryで子マシンを2つ作ってContextに保持します。
import { Machine, assign, spawn, send } from "xstate";
import { childMachine1 } from "./childMachine1";
export const parentMachine = Machine({
id: "parent-machine",
initial: "idle",
context: {
child1: null,
child2: null,
url: null
},
states: {
idle: {
entry: assign({
child1: () => spawn(childMachine1)
}),
on: {
"running.start": { target: "child1_run" }
}
},
child1_run: {
after: {
1000: {
actions: send({ type: "WAKE" }, { to: (context) => context.child1 })
}
},
on: {
"CHILD1.COMPLETE": { target: "child1_completed" }
}
},
child1_completed: {
always: { target: "final" }
},
final: {
type: "final"
}
}
});
Messaging
親 → 子
参考:https://xstate.js.org/docs/guides/actors.html#quick-reference
親側
イベントを送信
{
actions: send(
{ type: 'SOME_EVENT' },
{
to: (context) => context.someRef
}
);
}
データを含むイベントを送信
{
actions: send(
(context, event) => ({ ...event, type: 'SOME_EVENT' }),
{
to: (context) => context.someRef
}
);
}
イベントと特定のデータを送信
{
actions: send(
{ type: 'SOME_EVENT', data: someData },
{
to: (context) => context.someRef
}
);
}
子側
イベントを受信
SOME_EVENTでevent.data
を受信、fooへ遷移する。
fooState: {
on: {
SOME_EVENT: { target: foo },
},
},
イベントと特定のデータを受信
SOME_EVENTでevent.data
を受信し、ContextのsomeDataへ保管した後、fooへ遷移する。
fooState: {
on: {
SOME_EVENT: {
target: foo,
actions: assign({
someData: (context, event) => event.data,
}),
},
},
},
子 → 親
子側
親へイベントを送信
{
actions: sendParent({ type: 'ANOTHER_EVENT' });
}
親へイベントとデータを送信
{
actions: sendParent((context, event) => ({
...context,
type: 'ANOTHER_EVENT'
}));
}
{
actions: sendParent((context, event) => ({
type: 'ANOTHER_EVENT',
{foo: data}
}));
}
親側
イベントを受信
barState: {
...
on: {
COMPLETE: { target: "complete", }
}
},
遅延
barState: {
...
on: {
COMPLETE: { target: "complete", { delay: 1000 }}
}
},
へイベントとデータを受信
barState: {
on: {
COMPLETE: {
actions: assign({
todos: (_, event) => event.foo
}),
target: "complete"
}
}
},