React finite state machine
npm install react-finite-state-machineReact component that implements the logic of the finite-state machine.
Allows describing the component's state and the logic behind interstate transitions, transferring useful data between stages.
#### FSM Component Props
| Property | Type | Required? | Description |
|:---|:---|:---:|:---|
| meta | Meta | ✓ | Metdata. Description of stages. |
| onFinish | OnFinish | | Hook activated after the transition to the final stage, finish() method call in the component. |
| beforeTransition | BeforeTransition | | Hook activated before the transition to the preset stage. It's possible to interrupt the transition to the preset stage by returning false or Promise
| afterTransition | AfterTransition | | Hook activated after the transition to the preset stage. |
| Layout | React.ReactType
| commonProps | any | | General parameters that will be sent to each node component of a finite state machine |
``js
type StageName = string | number;
/**
* History of interstage transitions
*/
interface IHistory {
/* Number of records in history /
recordsCount: number;
/* Link to the first record's object in history /
first: IStage | null;
/* Link to the last record's object in history /
last: IStage | null;
/**
* Method of adding a new record to history
* @param {StageName} stageName Stage name
* @param {any} payload
* @returns {void}
*/
add: (stageName: StageName, payload: any) => void;
}
type Meta
/* List of stages and corresponding components ('name-component' pair) /
stages: {
[name in Stage]: React.ElementType
};
/* Initial stage /
initialStage: Stage;
/* Final stage /
finalStage: Stage;
};
type OnFinish: (transitionsHistory: IHistory) => void;
type BeforeTransition = (currentStage: StageName, nextStage: StageName, payload?: any) => boolean;
type AfterTransition = (currentStage: StageName, prevStage: StageName, payload?: any) => void;
type CommonProps = any;
type Layout = React.ElementType
`
#### Stage Component Props
| Property | Type | Description |
|:---|:---|:---|
| transition | Transition | Method of transition to the present stage. Can accept useful data for transferring to the next stage. |
| toPrevious | ToPrevious | Method of returning to the preceding stage. Can accept useful data for transferring to the previous stage. |
| finish | () => void | Calls onFinish hook. |
| payload | IncomingPayload | Data transferred from the preceding stage. |
| commonProps | any | General parameters that will be sent to each node component of a finite state machine |
`js
type IncomingPayload = {} | void;
type OutGoingPayload = {} | void;
type ToPrevPayload = OutGoingPayload;
type Transition = (stageName: StageName, payload?: OutGoingPayload) => Promise
type ToPrevious = (payload?: ToPrevPayload) => Promise
type CommonProps = any;
`
js
import React from 'react';
import ReactDOM from 'react-dom';
import {FSM} from 'react-fsm';const commonProps = {
key: 'value'
};
const Layout = ({children, currentStage, currentStagePayload}) => (
{children}
);const Stage = {
Stage1: 'Stage1',
Stage2: 'Stage2',
Stage3: 'Stage3'
};
const formsMeta = {
stages: {
[Stage.Stage1]: ({transition}) => (
transition(Stage.Stage2)}>
Stage 1
),
[Stage.Stage2]: ({transition}) => (
transition(Stage.Stage3)}>
Stage 2
),
[Stage.Stage3]: ({finish}) => (
finish()}>
Stage 3
)
},
initialStage: Stage.Stage1,
finalStage: Stage.Stage3
};const Form = () => (
meta={formsMeta}
afterTransition={(currentStage, prevStage, payload) => {
console.log(
We've made a transition to the stage ${currentStage},
From stage ${prevStage},
Received payload: ${payload}
);
}}
beforeTransition={(currentStage, nextStage, payload) => {
console.log(
Try to make a transition to the stage ${nextStage},
From stage ${prevStage},
With payload: ${payload}
); return !!payload.hasCats;
}}
onFinish={(transitionsHistory) => {
console.log(
Finish. History: ${transitionsHistory});
}}
commonProps={commonProps}
Layout={Layout}
/>
);ReactDOM.render(
,
document.getElementById('example')
);
``