javascript - 如何防止 XState 节点在接收事件时重置其子并行状态?
问题描述
我正在探索 XState 世界并尝试重新创建本次演讲中提到的机器@davidkpiano
并且面临着正确进行过渡的问题。当我向父机器发送消息时,它会重置所有子机器。
例如:我希望机器在我一个接一个地触发CHANGE和FOCUS事件后处于肮脏和专注的状态。但是在发送FOCUS消息后,原始状态会重置回原始状态。
我发现了这个问题,但是多个转换做同样的事情(正如它在问题本身中实际描述的那样)
另外,我不想将有关原始、聚焦和触摸状态的所有信息存储到 context 中,因为它不会像使用状态机那样安全。
下面的代码可复制粘贴到https://xstate.js.org/viz/
const createPristineMachineConfig = (inputName) => {
return {
id: `${inputName}.pristine`,
initial: 'pristine',
states: {
pristine: {
on: {
[`${inputName}.CHANGE`]: 'dirty',
},
},
dirty: {
type: 'final',
},
},
};
};
const createTouchedConfig = (inputName) => {
return {
id: `${inputName}.touched`,
initial: 'untouched',
states: {
untouched: {
on: {
[`${inputName}.TOUCH`]: 'touched',
},
},
touched: {
type: 'final',
},
},
};
};
const createFocusedMachineConfig = (inputName) => {
return {
id: `${inputName}.focused`,
initial: 'blurred',
states: {
blurred: {
on: {
[`${inputName}.FOCUS`]: 'focused',
},
},
focused: {
on: {
[`${inputName}.BLUR`]: 'blurred',
},
},
},
};
};
const createInputMachineConfig = (inputName) => ({
id: inputName,
type: 'parallel',
context: {
value: '',
},
on: {
FOCUS: {
actions: send(`${inputName}.FOCUS`),
internal: true,
},
BLUR: {
actions: [send(`${inputName}.TOUCH`), send(`${inputName}.BLUR`)],
internal: true,
},
CHANGE: {
actions: [assign((ctx, event) => ({ ...ctx, value: event.payload.value })), send(`${inputName}.CHANGE`)],
internal: true,
},
},
states: {
pristine: createPristineMachineConfig(inputName),
touched: createTouchedConfig(inputName),
focused: createFocusedMachineConfig(inputName),
},
});
const loginInputMachine = Machine(createInputMachineConfig('login'));
解决方案
也许这是因为dirty
是最终状态,例如:
{
id: 'loginForm',
initial: 'idle',
context: {
error: undefined,
},
invoke: [
{
id: 'usernameInput',
src: inputMachine,
},
{
id: 'passwordInput',
src: inputMachine,
},
{
id: 'loginButton',
src: buttonMachine,
},
],
states: {
idle: {
},
processing: {
},
finished: {
},
failed: {
},
},
};
我有这台产生一些演员的机器,我可以通过loginForm
以下方式通过机器访问loginForm.state.children.usernamInput
,但如果其中一台机器达到最终状态,它会返回未定义。
推荐阅读
- reactjs - 拖动 tomkp/react-split-pane 的调整大小后无法设置 defaultSize
- node.js - CERT_HAS_EXPIRED - 在从节点 js 到 php 的 post 请求中
- html - 表格主体元素与标题元素重叠
- javascript - 在构建基于 JavaScript 的 Web 浏览器时减少 CPU 使用率的方法
- reactjs - Symfony,React:生产服务器上的 api/var/log/prod.log 为空
- python - 如何根据另一个值列表拆分列表?
- notepad++ - 替换仅包含特定字符的文本 Notepad++
- docker - 我 Docker 是否 CMD 指令添加了一层?
- python - 使用 SharedMemoryManager 在进程之间进行通信时出现 EOFError
- python - 使用 astropy fit_wcs_from_points 给 FITS 文件一个新的 WCS