carloslfu / xstate-router

XState Router. Add routes to your XState machine.
MIT License
112 stars 16 forks source link

Browser back button / history pop causes an infinite loop #14

Closed ishabo closed 4 years ago

ishabo commented 4 years ago

I am using the useRouterMachine where all states have a path in each meta object.

  const history = createBrowserHistory();
  const { state, send, service } = useRouterMachine({
    config,
    options,
    initialContext,
    history,
  });

Each state has a NEXT and PREV event to navigate between states forwards and backwards. This works without a problem.

But the minute I click the browser back button, which triggers history action POP, nothing happens on the page (meaning it doesn't jump back) and the browser console spits out this message:

Warning: Event "route-changed" was sent to stopped service "(machine)". This service has already reached its final state, and will not transition.
Event: {"type":"route-changed","dueToStateTransition":false,"route":"/enrolment/declaration","service":{"id":"(machine)"}}

Now since useRouterMachine uses useMachine from @xstate/react I realised that it stops the service on unmount https://github.com/davidkpiano/xstate/blob/master/packages/xstate-react/src/index.ts#L97 .. and on history POP the component gets unmounted, hence pushing event route-changed results in this error.

The issue exacerbates the second I fire any other event like NEXT on my state machine, which triggers an infinite loop (resulting in the same warning in the console showing like 10 times / second) which breaks the browser and I have to force close it.

I have a solution for this, will attach a PR shortly.

carloslfu commented 4 years ago

Thanks for reporting and fixing it @ishabo.