@bemedev/x-react-signal v0.0.5
React XState interpreter
A simple function that use XState with Maverick's signal
Short introduction
Xstate
XState is a implementation of Statecharts, a graphical way to represent complexity in code.
Problems
- Complexity of React context :
When hooks were introduced, everyone was very happy. But with useState and useReducer, you cannot share data between components. So you need another function : createContext. But it cames with some complexity. So the “createContext” function returns a component named Provider. You need to wrap all components inside the Provider so you can use another hook “useContext”. Again three steps to share just a variable. It appears that it add more complexity than solutions.
- Recommend way to use XState globally :
- In XState docs, it’s recommended to use react context to have a global service shareable between components. The procedure is tedious but it works like a charm.
- Statecharts are usually big and has can have compound states, with many events. So it’s unusual to use it only in one component.
- Version 13 of Next.js :
The new app directory contains only server components by default. To use react context, you need to mark the component as client component. So the upper in the stack a client component is added, the harder you lose the benefits of SSR.
The solution
Just a simple function createSignal. It’s a object with signals to watch the state of your machine.
It accepts the same arguments as XState function interpret.
It returns some functions :
{
"start": "Start the interpreter (The same as Xstate Interpreter)",
"stop": "Stop the interpreter (The same as Xstate Interpreter)",
"send": "Send Event to the machine (The same as Xstate Interpreter)",
"sender": {
"definition": "A new way to simplify sending events",
"example": {
"event": {
"type": "INPUT",
"input": "string"
},
"prepareFunction": "const mySend = sender('INPUT')",
"usage": "mySend({ input: 'name' })"
}
},
"createSelector": "Create selector for all the state",
"createContextSelector": "Create selector inside the 'state.context'",
"createSelector": "Create selector for all the state",
"reducer": "Create a reducer to build a new selector"
/* ... */
}
, and signals :
{
"computed": "Select an element inside the current state.",
"context": "Select an element inside the current 'state.context'.",
"matches": "Macther for the value of the current state (not from XState, derived from @bemedev/x-matches).",
"hasTags": "Macther for tags of current value. Accept param array."
}
NB : Check the Library : @bemedev/x-matches to see how matches works.