Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Zag | 2,202 | 29 | 16 hours ago | 100 | July 15, 2022 | 10 | mit | TypeScript | ||
Finite state machines for building accessible design systems and UI components. | ||||||||||
React Automata | 1,293 | 13 | 4 | 4 years ago | 27 | August 27, 2018 | 14 | mit | JavaScript | |
A state machine abstraction for React | ||||||||||
Little State Machine | 1,269 | 2 months ago | 8 | mit | TypeScript | |||||
📠 React custom hook for persist state management | ||||||||||
React | 437 | 41 | 16 | 4 months ago | 29 | July 27, 2021 | 43 | mit | TypeScript | |
🔼 UI-Router for React | ||||||||||
React Transition State | 247 | 4 | 4 days ago | 21 | September 07, 2022 | 9 | mit | JavaScript | ||
Zero dependency React transition state machine | ||||||||||
Use Machine | 222 | 2 years ago | 12 | February 21, 2020 | 4 | mit | TypeScript | |||
React Hook for using Statecharts powered by XState. use-machine. | ||||||||||
Xstate Examples | 123 | 2 days ago | 2 | TypeScript | ||||||
Practical examples of statechart-based solutions with xstate. | ||||||||||
Xoid | 101 | 2 days ago | 15 | February 20, 2022 | 2 | mit | TypeScript | |||
Framework-agnostic state management library designed for simplicity and scalability ⚛ | ||||||||||
React Machinery | 101 | 2 years ago | 6 | July 04, 2018 | 11 | mit | JavaScript | |||
🔥 React Machinery provides a simple to use, component based approach to state machines in react. | ||||||||||
Swiftelm | 91 | 4 years ago | 1 | mit | Swift | |||||
Reactive + Automaton + VTree in Swift, inspired by Elm. |
Use Statecharts in React powered by XState, using the useMachine
hook. This is a minimalistic implementation (just 30 lines) that integrates React and XState.
Install it with: npm i use-machine
See --> the live example here!.
Let's build something with it:
import React, { useContext } from 'react'
import ReactDOM from 'react-dom'
import { assign } from 'xstate/lib/actions'
import { useMachine } from 'use-machine'
const incAction = assign(context => ({ counter: context.counter + 1 }))
const machineConfig = {
initial: 'Off',
context: {
counter: 0
},
states: {
Off: { on: { Tick: { target: 'On', actions: [incAction, 'sideEffect'] } } },
On: { on: { Tick: { target: 'Off', actions: incAction } } }
}
}
const MachineContext = React.createContext()
function App() {
const machine = useMachine(machineConfig, {
actions: {
sideEffect: () => console.log('sideEffect')
}
})
function sendTick() {
machine.send('Tick')
}
return (
<div className="App">
<span
style={{
backgroundColor: machine.state.matches('Off') ? 'red' : 'yellow'
}}
>
{machine.state.matches('Off') ? 'Off' : 'On'}
</span>
<button onClick={sendTick}>Tick</button>
Pressed: {machine.context.counter} times
<MachineContext.Provider value={machine}>
<div className="childs">
<Child />
</div>
</MachineContext.Provider>
</div>
)
}
function Child() {
const machine = useContext(MachineContext)
return (
<div>
<div>
Child state: {machine.state.matches('Off') ? 'Off' : 'On'}
</div>
<div>Child count: {machine.context.counter}</div>
<OtherChild />
</div>
)
}
function OtherChild() {
const machine = useContext(MachineContext)
function sendTick() {
machine.send('Tick')
}
return (
<div>
<div>
OtherChild state: {machine.state.matches('Off') ? 'Off' : 'On'}
</div>
<div>OtherChild count: {machine.context.counter}</div>
<button onClick={sendTick}>Tick 2</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
This library is written in TypeScript, and XState too, so we have excellent support for types.
Example:
import React, { useContext } from 'react'
import ReactDOM from 'react-dom'
import { MachineConfig } from 'xstate'
import { assign } from 'xstate/lib/actions'
import { useMachine, TCreateContext } from './use-machine'
type TContext = {
counter: number
}
type TSchema = {
states: {
Off: {},
On: {}
}
}
type TEvent = {
type: 'Tick'
}
const incAction = assign<TContext>(context => ({ counter: context.counter + 1 }))
const machineConfig: MachineConfig<TContext, TSchema, TEvent> = {
initial: 'Off',
context: {
counter: 0
},
states: {
Off: { on: { Tick: { target: 'On', actions: [incAction, 'sideEffect'] } } },
On: { on: { Tick: { target: 'Off', actions: incAction } } }
}
}
type TMachine = TCreateContext<TContext, TSchema, TEvent>
const MachineContext = React.createContext<TMachine>({} as TMachine)
function App() {
const machine = useMachine<TContext, TSchema, TEvent>(machineConfig, {
actions: {
sideEffect: () => console.log('sideEffect')
}
})
function sendTick() {
machine.send('Tick')
}
return (
<div className="App">
<span
style={{
backgroundColor: machine.state.matches('Off') ? 'red' : 'yellow'
}}
>
{machine.state.matches('Off') ? 'Off' : 'On'}
</span>
<button onClick={sendTick}>Tick</button>
Pressed: {machine.context.counter} times
<MachineContext.Provider value={machine}>
<div className="childs">
<Child />
</div>
</MachineContext.Provider>
</div>
)
}
function Child() {
const machine = useContext(MachineContext)
return (
<div>
<div>
Child state: {machine.state.matches('Off') ? 'Off' : 'On'}
</div>
<div>Child count: {machine.context.counter}</div>
<OtherChild />
</div>
)
}
function OtherChild() {
const machine = useContext(MachineContext)
function sendTick() {
machine.send('Tick')
}
return (
<div>
<div>
OtherChild state: {machine.state.matches('Off') ? 'Off' : 'On'}
</div>
<div>OtherChild count: {machine.context.counter}</div>
<button onClick={sendTick}>Tick 2</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)