A library built on top of xstate, that allows you to access your machines/services through your react application
A declarative state container built on top of xState
xState-store is a library built on top of xstate, that allows you to access your machines/services through your React application and simplify sharing the same instance/actor between your different components.
Why ?
Because xState and state machines are an awesome way to simplify complex applications logic especially for frontend applications using React library.
Sometimes we need to have a global store or make different components sharing the same logic coming form the same instance, it’s where xState-store can helps you.
Installation
Using npm:
$ npm install xstate-store xstate @xstate/react
Usage
xstate-store exposes multiple functions that will help you managing your global application states.
createInstance
To create a new machine instance, you could use createInstance
method that uses the createMachine
and interpret
functions from xstate behind the scenes.
createInstance(
instanceId: string // it's the unique id that will define the instance and helps us accessing it through the application
config: MachineDefinition // it's the machine definition that we pass to `createMachine` in xstate
options?: MachineOptions // optional: the options that would be passed to the xstate `createMachine` function
)
For example, if we want to create an instance with the id LIGHT_INSTANCE_ID
, we can do something like this:
const LIGHT_INSTANCE_ID = '_LIGHT_INSTANCE_ID_'
createInstance(LIGHT_INSTANCE_ID, {
id: 'test-machine',
initial: 'off',
context: {
usageNumber: 0,
},
states: {
off: {
on: {
TOGGLE: {
target: 'on',
actions: assign({
usageNumber: (context) => context.usageNumber + 1,
})
}
}
},
on: {
on: {
TOGGLE: 'off'
}
},
}
})
stopInstance
Like xstate does, you can stop the instance of your service using the stopInstance
function by passing the instanceId
.
stopInstance(LIGHT_INSTANCE_ID)
sendToInstance
sendToInstance
function allows you to send
events to your service using the same send
function from xState.
For example, if we want to send an event TOGGLE
to our previous service, we can do something like this:
sendToInstance(
LIGHT_INSTANCE_ID,
{ type: 'TOGGLE' }
)
useInstance
useInstance
hook works same as the useActor
function from xstate, you can pass directly your instanceId
to the hook in order to retrieve the current state
of the service and a send
function.
function MyComponent() {
const [state, send] = useInstance(LIGHT_INSTANCE_ID)
return (
<p>The light is now: <strong>{state.value}</strong></p>
);
}
useDataFromContext
useDataFromContext
hook allow us more easily accessing the context data through the application.
The purpose is that you can retrieve an object with defined values from the context directly.
The hook will return an object with all asked data passed as an array or string to the hook.
For example, in our previous instance we have a value usageNumber
in our context. we can retrieve and use it like this:
export default function Component2() {
const data = useDataFromContext(LIGHT_INSTANCE_ID, 'usageNumber')
// we can also pass an array to retrieve multiple values directly
// const data = useDataFromContext(LIGHT_INSTANCE_ID, ['usageNumber', 'otherData'])
return (
<p>
Number of light usage: <strong>{data.usageNumber}</strong>
</p>
)
}
Examples
What’s next ?
The library can cover a lot of use cases and the most simple ones. But there’s some improvements to come for it:
- useInstance
- useDataFromContext
- Add tests to the library
- Handle spawned machines
And other awesome stuffs.