有没有办法在 useEffect 的反应组件中设置 xstate 机器的状态?
Posted
技术标签:
【中文标题】有没有办法在 useEffect 的反应组件中设置 xstate 机器的状态?【英文标题】:Is there a way to set the state of an xstate machine in a react component in useEffect? 【发布时间】:2022-01-09 02:44:25 【问题描述】:我有以下 React.js 组件需要以下内容:
通过使用 fetch 调用服务器端 API 来保持单击按钮时的状态。 当组件初始化时,在调用useEffect
之后在组件中设置状态,该useEffect
使用fetch 调用服务器端API 以获取对象的当前状态。
这里是组件的显示
这是我目前所拥有的。
import React, useEffect, useState from 'react';
import useParams, useHistory from "react-router-dom";
import createMachine from 'xstate';
import useMachine from "@xstate/react";
import MagellanButton from "./Styles";
import 'bootstrap/dist/css/bootstrap.min.css';
import '../App.css';
const approvalMachine = createMachine(
id: 'approve',
initial: 'Not Submitted',
context:
retries: 0
,
states:
'Not Submitted':
on:
SUBMIT: 'Pending Approval'
,
'Pending Approval':
on:
CANCEL: 'Not Submitted',
CHANGE: 'Change Request',
DENIED: 'Denied',
APPROVED: 'Approved'
,
'Change Request':
on:
RESUBMITTED: 'Pending Approval',
CANCEL: 'Not Submitted'
,
Denied:
type: 'final'
,
Approved:
on:
PUBLISH: 'Published'
,
Published:
type: "final"
);
function MagellanStateManager(id)
const parameters = useParams();
const history = useHistory()
const [state, send] = useMachine(approvalMachine);
useEffect(() =>
, []);
return (
<span style=float: "right", marginTop: 8>
<span className="m-form-label ml-3">State:</span> <span>state.value</span>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('SUBMIT') onClick=() => send('SUBMIT')>Submit</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('CANCEL') onClick=() => send('CANCEL')>Cancel</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('CHANGE') onClick=() => send('CHANGE')>Change</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('RESUBMITTED') onClick=() => send('RESUBMITTED')>Resubmit</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('DENIED') onClick=() => send('DENIED')>Deny</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('APPROVED') onClick=() => send('APPROVED')>Approve</MagellanButton>
<MagellanButton className="ml-3" disabled=!state.nextEvents.includes('PUBLISH') onClick=() => send('PUBLISH')>Publish</MagellanButton>
</span>
)
export default MagellanStateManager;
【问题讨论】:
只要 API 响应是 xstate 的有效 JSON,the docs show the way to do it 【参考方案1】:从 Taxel 的评论中,我找到了解决方案。这是更改后的反应元素。我将不胜感激任何额外的 cmets 以使其变得更好。
谢谢!
import React, useEffect, useState from 'react';
import createMachine, interpret from 'xstate';
import MagellanButton from "./Styles";
import 'bootstrap/dist/css/bootstrap.min.css';
import '../App.css';
const approvalMachine = createMachine(
id: 'approve',
initial: 'Not Submitted',
context:
retries: 0
,
states:
'Not Submitted':
on:
SUBMIT: 'Pending Approval'
,
'Pending Approval':
on:
CANCEL: 'Not Submitted',
CHANGE: 'Change Request',
DENIED: 'Denied',
APPROVED: 'Approved'
,
'Change Request':
on:
RESUBMITTED: 'Pending Approval',
CANCEL: 'Not Submitted'
,
Denied:
type: 'final'
,
Approved:
on:
PUBLISH: 'Published'
,
Published:
type: "final"
);
function MagellanStateManager(id)
const [service, setService] = useState(interpret(approvalMachine));
const [counter, setCounter] = useState(0);
useEffect(() =>
// TODO: Add the fetch to get the stored state from the server
const approvalService = interpret(approvalMachine);
approvalService.start(approvalMachine.initialState);
setService(approvalService);
// TODO: Add dependencies for the useEffect for when identification values change
, []);
function storeState(theEvent)
const newState = service.send(theEvent);
const theState = JSON.stringify(newState);
// TODO: Add the fetch to send the state to the server to be stored
console.log(theState);
setCounter(counter + 1);
function notEvent(theEvent)
if (service != null && service._state != null)
return !service._state.nextEvents.includes(theEvent);
else
return true;
return (
<span style=float: "right", marginTop: 8>
<span className="m-form-label ml-3">State:</span> <span>service ? service._state ? service._state.value : "" : ""</span>
<MagellanButton className="ml-3" disabled=notEvent('SUBMIT') onClick=() => storeState('SUBMIT')>Submit</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('CANCEL') onClick=() => storeState('CANCEL')>Cancel</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('CHANGE') onClick=() => storeState('CHANGE')>Change</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('RESUBMITTED') onClick=() => storeState('RESUBMITTED')>Resubmit</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('DENIED') onClick=() => storeState('DENIED')>Deny</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('APPROVED') onClick=() => storeState('APPROVED')>Approve</MagellanButton>
<MagellanButton className="ml-3" disabled=notEvent('PUBLISH') onClick=() => storeState('PUBLISH')>Publish</MagellanButton>
</span>
)
export default MagellanStateManager;
【讨论】:
我已经构建了一个 React 样板和 XState,也许它对你有用 gitlab.com/disruptivo.io/internals/frontend/react-starter-kit 另外我在 Medium 上写了一篇关于它的简短帖子 medium.com/@luisbar180492/…以上是关于有没有办法在 useEffect 的反应组件中设置 xstate 机器的状态?的主要内容,如果未能解决你的问题,请参考以下文章
React - useEffect axios请求中设置的状态为空