Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sielay/usestatetransition
Other flavor of a state machine hook
https://github.com/sielay/usestatetransition
Last synced: 1 day ago
JSON representation
Other flavor of a state machine hook
- Host: GitHub
- URL: https://github.com/sielay/usestatetransition
- Owner: sielay
- Created: 2021-12-11T18:14:43.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2021-12-13T16:58:20.000Z (about 3 years ago)
- Last Synced: 2024-12-04T10:02:46.682Z (19 days ago)
- Language: TypeScript
- Size: 160 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# useStateTransition
If you look for a classic state machine, check [cassiozen/useStateMachine](https://github.com/cassiozen/useStateMachine).
## Problem
One of my project is an app that can open various editors. Each editor can have different implementation, but needs to follow the same lifecycle. I wanted to provide a neat small hook that would handle it, so specific editors don't have too keep too much knowledge about the host app.
While doing it turned out I need some sort of state machine. The difference was that I need it to be focused more on transition between specific states.
Other nice projects implementing state machine hook were following enter/leave version of the pattern, that was focused on the state, rather than transition.
## Example
Check the [tests example](./src/__tests__/example/useEditor.tsx).
```ts
const { state, dispatch } = useStateTransition({
initial: EditorState.INIT,
flows: [
{
from: EditorState.INIT,
to: EditorState.READY,
on: (_, setState) => {
setState(scenario === "new" ? EditorState.NEW : EditorState.LOAD);
},
},
{
from: [EditorState.NEW, EditorState.LOAD],
to: EditorState.OPEN,
},
],
});
```## API
```ts
const { state, dispatch, error } = useStateTransition(options)
```### state
Current state of provided `StateType`. The first value comes from `initial` field in `options`.
### dispatch
```ts
type Dispatch = (requestedState: StateType, data?: unknown) => void;
```You use it to trigger the transition. Transition to the same state won't trigger any updates. If the request create unknown transition `error` will be populated.
#### Conditional dispatch
You can pass a function to dispatch to decide which state you dispatch to based on the current state. It's useful when you dispatch comes from useCallback which would cache the initial state
```ts
dispatchFn((currentState, data) => {
if (currentState = 1) {
return {
to: 2,
data // you can decide to pass the data
}
}
return {
to: 3
// or to filter out the data
}
}```
### error
Display the latest error. At the moment it reports only about unknown transitions.
### options
You need to define the `initialValue` of the state and the flows.
```ts
{
initialValue: StateType,
flows: Flow[]
}
```### Flow
```ts
{
from: StateType | StateType[],
to: State | StateType[],
on?: (requestedState: StateType, setState: (state: StateType) => void, data?: unknown) => void;
}
```* `from` defines the state you want to transition from; you can specify one or many states.
* `to` defines the state you want to transition to; you can specify oen or many states.
* `on` (optional)
* if absent the state machine will just allow transition
* if present it works like a guard, in the end you can specify which state you want to set. It won't trigger another guard or test, it will just update the sate.
* you have access to `data` passed, so you can update your other hooks.
* it happens in `useEffect`## License
MIT