有没有办法在 useEffect 的反应组件中设置 xstate 机的状态?
Is there a way to set the state of an xstate machine in a react component in useEffect?
我有以下 React.js 组件需要以下内容:
- 通过使用 fetch 调用服务器端来保持单击按钮时的状态 API。
- 组件初始化时调用
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;
从 Taxel 的评论中,我找到了我的解决方案。这是更改后的反应元素。我将不胜感激任何额外的评论,使它变得更好。
谢谢!
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.js 组件需要以下内容:
- 通过使用 fetch 调用服务器端来保持单击按钮时的状态 API。
- 组件初始化时调用
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;
从 Taxel 的评论中,我找到了我的解决方案。这是更改后的反应元素。我将不胜感激任何额外的评论,使它变得更好。
谢谢!
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;