0

I've inherited a react project using xState which is pretty unknown to me. In this machine there is a "saving" state having a few substates.

Something like this:

states : {
      saving: {
        id: 'saving',
        initial: 'saving',
        states: {
          saving: {
            invoke: {
              src: 'updateService',
              onDone: [
                {
                  target: 'fetchSchooldays',
                  actions: 'setKursus',
                  cond: 'dateChange',
                },
                {
                  target: '#idle',
                  actions: 'setKursus',
                },
              ],
              onError: [
                //not interesting
              ],
            },
          },
          fetchSchooldays: {
            invoke: {
              //Not interesting
            },
          },
        },
      },
}

in the react-page I see this:

const [state, send, kursusService] = useMachine([the machine]);

Now I want to do something (just a console.log is fine) when the saving.saving (updateService) service is done but I cant figure it out.

I have been looking at documentation and examples, but I believe I need some pointers to where to begin monitoring a substate-change from outside the machine.

-- Addendum 1 ----- This morning I tried making a "between"-state :

 saveDone : {
    on : {
      '' : [
        {
        target: 'fetchSchooldays',
        cond: 'dateChange',
      },
        { target : '#idle'}
      ]
    }

  },

I hoped I could detect this state and trigger my event and I can if I remove {target : '#idle'}, but then I won't ever hit the #idle in the root. if the {target : '#idle'} is present, it just seems to skip past this state.

Henrik Clausen
  • 679
  • 6
  • 16

1 Answers1

0

You can add an action to the actions: [] array (can be a single value or an array):

onDone: [
  {
    // ...
    actions: ['setKursus', () => { console.log('hi') }]
  },
  // ...
]

The interpreted machine can also listen to state changes:

const service = interpret(machine).start();

service.subscribe(state => {
  console.log(state);
});
David Khourshid
  • 4,918
  • 1
  • 11
  • 10
  • Thanks. Your first suggestion, can that somehow invoke a function outside the machine? I've been looking into the subscriptions, but as far as I can tell, it doesn't trigger on change of substates. – Henrik Clausen Jun 15 '22 at 03:27
  • @xstate/react has a useSelector function you can use. Combine that with a useEffect and you should be good https://xstate.js.org/docs/packages/xstate-react/ – Sean Nilan Jun 22 '22 at 04:59