关于send内置动作的含义、用法及事件未捕获问题求助
Hey there! Let's break down XState's send built-in action first, then fix the issue you're seeing with your parallel state machine.
send Action What is send?
The send action is XState's core way to dispatch events to a state machine (or specific services within it). Think of it as sending a "signal" that tells the machine (or a part of it) to react—whether that's transitioning states, running other actions, or triggering behavior in another part of the machine.
Common Usage Patterns
Here are the most frequent ways to use send:
- Basic named event: Dispatch a simple, string-named event:
send('USER_SUBMITTED') - Event with payload: Send an event with attached data for the machine to use:
send({ type: 'DATA_LOADED', payload: { items: ['apple', 'banana'] } }) - Send to a specific target: By default,
sendsends the event to the current service (the state/state node where the action is defined). To send to another service (like a parallel state node or child machine), use thetooption:// Send to the root state machine (all nodes can listen for it) send('TRIGGER_ACTION', { to: '#' }) // Send directly to a specific parallel state node (by its ID) send('TRIGGER_ACTION', { to: 'firstParallelNode' }) - Delayed send: Dispatch the event after a set time delay:
send('TIMER_EXPIRED', { delay: 3000 }) // Sends after 3 seconds
Fixing Your Parallel State Machine Issue
The problem in your example boils down to event scope: when your second parallel state node uses send, it's only sending the event to itself—not the other parallel node or the root machine. Parallel state nodes act as independent services, so events don't automatically propagate between them unless you specify a target.
Let's use a simplified version of your machine to illustrate:
const machine = createMachine({ type: 'parallel', states: { nodeA: { on: { MY_EVENT: { actions: () => console.log('Node A received the event!') } } }, nodeB: { entry: send('MY_EVENT') // Defaults to sending to nodeB only } } });
Here, nodeA is listening for MY_EVENT, but the event is only sent to nodeB—so nodeA never catches it.
The Solution
Update the send action to target the root machine (so both parallel nodes can receive the event) or the specific node you want to trigger:
nodeB: { // Send to the root machine—both nodes can respond to the event entry: send('MY_EVENT', { to: '#' }) }
Or if you only want nodeA to receive the event:
nodeB: { entry: send('MY_EVENT', { to: 'nodeA' }) }
With this change, the event will be dispatched to the right place, and your target state node will capture it as expected.
内容的提问来源于stack exchange,提问作者marcos82

