# 事件
¥Events
这些 XState v4 文档不再维护
XState v5 现已推出!阅读有关 XState v5 的更多信息 (opens new window)
¥XState v5 is out now! Read more about XState v5 (opens new window)
🆕 了解有关 XState 中的事件 (opens new window) 和 以小狗为特性的事件和转场的无代码介绍 (opens new window) 的更多信息。
¥🆕 Find more about events in XState (opens new window) as well as a no-code introduction to events and transitions featuring puppies (opens new window).
事件是导致状态机从当前 state 到下一个状态 transition 的原因。要了解更多信息,请阅读 状态图简介中的事件部分。
¥An event is what causes a state machine to transition from its current state to its next state. To learn more, read the events section in our introduction to statecharts.
# API
事件是一个具有 type
属性的对象,表示它是什么类型的事件:
¥An event is an object with a type
property, signifying what type of event it is:
const timerEvent = {
type: 'TIMER' // the convention is to use CONST_CASE for event names
};
在 XState 中,只有 type
的事件可以仅用其字符串类型表示,作为简写:
¥In XState, events that only have a type
can be represented by just their string type, as a shorthand:
// equivalent to { type: 'TIMER' }
const timerEvent = 'TIMER';
事件对象还可以具有其他属性,这些属性表示与事件关联的数据:
¥Event objects can also have other properties, which represent data associated with the event:
const keyDownEvent = {
type: 'keydown',
key: 'Enter'
};
# 发送事件
¥Sending events
正如 转场指南 中所解释的,在给定当前状态和事件(在其 on: { ... }
属性上定义)的情况下,转换定义了下一个状态。这可以通过将事件传递到 转场法 来观察:
¥As explained in the transitions guide, a transition defines what the next state will be, given the current state and the event, defined on its on: { ... }
property. This can be observed by passing an event into the transition method:
import { createMachine } from 'xstate';
const lightMachine = createMachine({
/* ... */
});
const { initialState } = lightMachine;
nextState = lightMachine.transition(nextState, { type: 'TIMER' });
console.log(nextState.value);
// => 'red'
许多原生事件(例如 DOM 事件)是兼容的,并且可以通过在 type
属性上指定事件类型来直接与 XState 一起使用:
¥Many native events, such as DOM events, are compatible and can be used directly with XState, by specifying the event type on the type
property:
import { createMachine, interpret } from 'xstate';
const mouseMachine = createMachine({
on: {
mousemove: {
actions: [
(context, event) => {
const { offsetX, offsetY } = event;
console.log({ offsetX, offsetY });
}
]
}
}
});
const mouseService = interpret(mouseMachine).start();
window.addEventListener('mousemove', (event) => {
// event can be sent directly to service
mouseService.send(event);
});
# 空事件
¥Null events
警告
空事件语法 ({ on: { '': ... } })
将在版本 5 中弃用。应改用新的 always 语法。
¥The null event syntax ({ on: { '': ... } })
will be deprecated in version 5. The new always syntax should be used instead.
空事件是没有类型的事件,一旦进入状态就会立即发生。在转换中,它由空字符串 (''
) 表示:
¥A null event is an event that has no type, and occurs immediately once a state is entered. In transitions, it is represented by an empty string (''
):
// contrived example
const skipMachine = createMachine({
id: 'skip',
initial: 'one',
states: {
one: {
on: { CLICK: 'two' }
},
two: {
// null event '' always occurs once state is entered
// immediately take the transition to 'three'
on: { '': 'three' }
},
three: {
type: 'final'
}
}
});
const { initialState } = skipMachine;
const nextState = skipMachine.transition(initialState, { type: 'CLICK' });
console.log(nextState.value);
// => 'three'
空事件有很多用例,特别是在定义 瞬态转变 时,其中(可能是 transient)状态立即确定下一个状态应基于 conditions:
¥There are many use cases for null events, especially when defining transient transitions, where a (potentially transient) state immediately determines what the next state should be based on conditions:
const isAdult = ({ age }) => age >= 18;
const isMinor = ({ age }) => age < 18;
const ageMachine = createMachine({
id: 'age',
context: { age: undefined }, // age unknown
initial: 'unknown',
states: {
unknown: {
on: {
// immediately take transition that satisfies conditional guard.
// otherwise, no transition occurs
'': [
{ target: 'adult', cond: isAdult },
{ target: 'child', cond: isMinor }
]
}
},
adult: { type: 'final' },
child: { type: 'final' }
}
});
console.log(ageMachine.initialState.value);
// => 'unknown'
const personData = { age: 28 };
const personMachine = ageMachine.withContext(personData);
console.log(personMachine.initialState.value);
// => 'adult'