Need help with use-machine?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

carloslfu
229 Stars 13 Forks MIT License 61 Commits 10 Opened issues

Description

React Hook for using Statecharts powered by XState. use-machine.

Services available

!
?

Need anything else?

Contributors list

# 65,135
Svelte
xstate
meteor
GraphQL
24 commits
# 399,207
F#
Vim
React
xstate
2 commits
# 444,689
React
xstate
react-h...
TypeScr...
2 commits
# 452,644
React
xstate
react-h...
TypeScr...
1 commit
# 177,361
React
xstate
Shell
CSS
1 commit
# 177,219
HTML
node-mo...
node-js
React
1 commit
# 379,114
React
xstate
react-h...
F#
1 commit
# 654,213
React
JavaScr...
xstate
react-h...
1 commit

Build Status

use-machine

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 (

{machine.state.matches('Off') ? 'Off' : 'On'} Tick Pressed: {machine.context.counter} times <machinecontext.provider value="{machine}">
</machinecontext.provider>
) }

function Child() { const machine = useContext(MachineContext) return (

Child state: {machine.state.matches('Off') ? 'Off' : 'On'}
Child count: {machine.context.counter}
) }

function OtherChild() { const machine = useContext(MachineContext)

function sendTick() { machine.send('Tick') } return (

OtherChild state: {machine.state.matches('Off') ? 'Off' : 'On'}
OtherChild count: {machine.context.counter}
Tick 2
) }

const rootElement = document.getElementById('root') ReactDOM.render(, rootElement)

TypeScript

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(context => ({ counter: context.counter + 1 }))

const machineConfig: MachineConfig = { initial: 'Off', context: { counter: 0 }, states: { Off: { on: { Tick: { target: 'On', actions: [incAction, 'sideEffect'] } } }, On: { on: { Tick: { target: 'Off', actions: incAction } } } } }

type TMachine = TCreateContext

const MachineContext = React.createContext({} as TMachine)

function App() { const machine = useMachine(machineConfig, { actions: { sideEffect: () => console.log('sideEffect') } })

function sendTick() { machine.send('Tick') }

return (

{machine.state.matches('Off') ? 'Off' : 'On'} Tick Pressed: {machine.context.counter} times <machinecontext.provider value="{machine}">
</machinecontext.provider>
) }

function Child() { const machine = useContext(MachineContext) return (

Child state: {machine.state.matches('Off') ? 'Off' : 'On'}
Child count: {machine.context.counter}
) }

function OtherChild() { const machine = useContext(MachineContext)

function sendTick() { machine.send('Tick') } return (

OtherChild state: {machine.state.matches('Off') ? 'Off' : 'On'}
OtherChild count: {machine.context.counter}
Tick 2
) }

const rootElement = document.getElementById('root') ReactDOM.render(, rootElement)

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.