koordinates / xstate-tree

Build UIs with Actors using xstate and React
MIT License
85 stars 6 forks source link

Allow passing callbacks to slot views/root components to allow communication with React from xstate machines #60

Open UberMouse opened 7 months ago

UberMouse commented 7 months ago

This is a not uncommon scenario, where you have a function that only exists in React land that you want to call from an event in an xstate machine. The current solution to that is to push the callback function into the machines context so it may call it.

With xstate 5.9.0s addition of event emitters it should be possible to come up with a solution that allows using event emitters to call supplied React functions passed as props to the slots view.

ie something like this

// In the child machine to be invoked into the slot
export type EmittedEvents = { type: "someEvent", bar: string}
const machine = setup({
  types: {
    emitted: {} as EmittedEvents
  },
}).createMachine({
  entry: emit({type: "some-event", bar: "foo})
})

// In some parent machine that uses the slot
const someSlot = singleSlot("SomeSlot").withEmittedEvents<EmittedEvents>();
const slots = [someSlot]

const machine = createMachine({
  // .....
})

const XstateTreeMachine = createXStateTreeMachine(machine, {slots, View({slots}) {
  return <slots.SomeSlot onSomeEvent={({bar}) => console.log(bar)} />
}})

The same sort of functionality should also be exposed on root components