state machine driven routing (xstate & react-router integration) #3963
Replies: 4 comments 1 reply
-
|
I'm also interested in this approach too! it's very inspiring! just wondering have you tried something like https://github.com/carloslfu/xstate-router which add routes to your XState machine and maintain it in sync with the actual route? |
Beta Was this translation helpful? Give feedback.
-
|
FWIW, here are some resources:
|
Beta Was this translation helpful? Give feedback.
-
|
This might also be of interest: https://github.com/lit-apps/lit-app/tree/dev/packages/xstate-route It is a lit controller binding actor state machine with a router (router-slot) - very early preview. |
Beta Was this translation helpful? Give feedback.
-
|
This is a great example! But looks like there were breaking changes with both XState v4 to v5 and React Router v5 to v7. I forked the codesandbox https://codesandbox.io/p/sandbox/xstate-react-router-6k4rcg to upgrade to the latest XState 5, React 19, React Router 7, and TypeScript 5.8, and began upgrading to all the new APIs, but it's a work in progress. Some things don't seem to migrate well, such as meta on transitions. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm working on an integration between
xstate,@xstate/react, andreact-routerto manage complex flows in my application. The benefits that I thinkxstateoffers here is to consolidate routing logic that is currently spread throughout the application in a single place, and also provide documentation of these flows in statecharts. I've built a basic POC that works, but as anxstatenewbie I'd like to get some feedback on the implementation to see what could be improved.Here is a codesandbox with a basic implementation of the above integration: https://codesandbox.io/s/xstate-react-router-u472if?file=/src/App.js. I've commented it out to help provide context for various parts of the code.
To summarize the implementation, each state corresponds to a route path. Within each state, events correspond to CTAs on the page, e.g. a 'Continue' or 'Back' button. URL state is synced to the machine state using
history.pushwithin theservice.onTransitioncallback.I'm open to any and all feedback, but there are a couple points which I'm especially interested in getting feedback on:
tightening the integration between
xstateandreact-router(inMachineProvider.js)The current implementation uses
service.onTransitioninside auseEffectto watch for state changes and subsequently callhistory.pushorhistory.replaceto sync the url state to the machine state.To manage
popstateevents I have a separate subscription usingreact-router'shistory.listen. The callback tohistory.listenchecks forpopstateevents to send an event (named 'syncState') to the machine to set the machine state to the currentpathname.Is there a better point of integration between the two libraries, so that url state is driven by the
xstatestate machine that still allows the machine state to sync topopstateevents or navigation by url? Am I mixingxstateparadigms by using bothservice.onTransitionanduseInterprethook?protected route patterns and managing redirects
What is the best way to protect routes behind a certain condition so that if a user tries to navigate directly to a route by url, the app will redirect to a different route if the condition is not met? Does it make sense to use an
entryaction that reads a value fromcontextandhistory.pushif the condition is not met? or is there an alternative approach?What about the case where we are checking for a value in
location.stateand if it is not there, we want to redirect back to the page/form where that value should be set viahistory.push('/route', state)? seeForm3.jsxIs there a way to handle this so that all of the redirect logic/action is contained within the state machine?
root redirects where a user is navigated to one of several routes based on conditional logic (in
useCreateMachine.tsx)In my implementation, at the initial state
"/"Iinvokean api call that is set to context and sets the machine state to"_redirect_". This state has analwaysdetermines where to redirect the user based on conditionalguards. Is there a better way to do this where I don't need a"_redirect_"state? It stands out as the only state in the machine which is not associated to a route.Again, I'd appreciate any feedback on this approach and if anyone else has tackled this integration I'd be really curious to see some alternate approaches.
**note - will have to update away from using
history.listenas it no longer exists inreact-router v6. the newuseNavigationTypehook will probably fill the gapBeta Was this translation helpful? Give feedback.
All reactions