cassiozen / useStateMachine

The <1 kb state machine hook for React
MIT License
2.38k stars 47 forks source link

[QUESTION] Conditional transitions and guards #46

Closed arthurdenner closed 3 years ago

arthurdenner commented 3 years ago

Hey! 👋🏽

I've been exploring the library and I was wondering how guards fit when talking about "conditional transitions" - I'm not sure that's the proper name for the scenario below.

Consider the following scenario:

  1. Initial state has an effect that performs some action - doesn't matter if sync or async
  2. Based on a condition, it should transition to one of two possible states - A or B

My question is about what one should do in other to transition to A or B.

Currently, the guard feature works when transitioning to a specific state - it can either proceed with the transition to that state or stay in the current state, depending on the boolean value returned by the guard function.

From what I understood, the only way to perform a "conditional transition" is doing the check inside the effect and calling send accordingly.

Example ```js initial: { on: { GO_TO_A: 'A', GO_TO_B: 'B', }, effect(send) { send(condition ? 'GO_TO_A' : 'GO_TO_B'); }, }, ```

I was wondering if it fits the state machine model (and this library's goal of course) to have guarded transitions where one could transition to the next state based on the guard result. Something like, "if guard returns true, go to A, otherwise go to B".

Example ```js // the names are just for clarification purpose initial: { on: { NEXT_STATE: { guard: (...args) => boolean, targetIfTruthy: 'A', targetIfFalsy: 'B', }, }, effect(send) { send('NEXT_STATE'); }, }, ```

xstate has guarded transitions, but the signature is an array and I think one can put as many {target, cond} items as needed.

My question/proposal relates to conditionally transitioning between two states but I linked their approach in case you see the value and decide to implement the feature similarly - with many possible next states.

If something above isn't clear or if there's a way to accomplish what's proposed here, let me know.

cassiozen commented 3 years ago

That's a great question. And yep, this is not supported in useStateMachine. useStateMachine strives to be very small, and as a consequence, it also has a very small set of features.

I would be open to a PR, but being honest there are other things I would consider having priority over this, like hierarchical states.