Skip to content

Instantly share code, notes, and snippets.

@mikaelkaron
Created June 7, 2019 13:38
Show Gist options
  • Save mikaelkaron/0e8f1f0559d4776144e8a263a3bfa6b2 to your computer and use it in GitHub Desktop.
Save mikaelkaron/0e8f1f0559d4776144e8a263a3bfa6b2 to your computer and use it in GitHub Desktop.
App XState machine with routing
// Available variables:
// Machine (machine factory function)
// assign (action)
// XState (all XState exports)
const send = XState.send;
const fetchMachine = Machine({
id: 'app',
initial: 'anonymous',
context: {
authenticated: false
},
states: {
anonymous: {
on: {
'': {
target: 'authenticated.current',
cond: 'isAuthenticated',
},
},
meta: {
component: 'is-anonymous'
}
},
authenticated: {
initial: 'home',
states: {
home: {
entry: send({
type: 'ROUTED',
url: '/'
}),
},
account: {
entry: send({
type: 'ROUTED',
url: '/account'
}),
},
test: {
initial: 'overview',
states: {
overview: {
entry: send({
type: 'ROUTED',
url: '/tests'
}),
},
details: {
entry: [assign({ params: (ctx, event) => event.params || ctx.params }), send(ctx => ({
type: 'ROUTED',
url: `/tests/${ctx.params.testId}`,
})), console.log],
}
},
on: {
OVERVIEW: '.overview',
DETAILS: {
target: '.details',
internal: false,
cond: (_ctx, event) => !!(event.params && event.params.testId)
},
},
meta: {
component: 'is-test'
}
},
current: {
type: 'history',
history: 'deep'
},
},
on: {
'': {
target: 'anonymous',
cond: 'isNotAuthenticated',
},
HOME: {
target: '.home',
},
ACCOUNT: '.account',
TEST: '.test'
},
meta: {
component: 'is-authenticated'
}
}
},
on: {
LOGIN: {
actions: assign({ authenticated: true }),
target: 'authenticated.current',
},
LOGOUT: {
actions: [assign({ authenticated: false })],
target: 'anonymous'
},
ROUTE: [
{
target: 'authenticated.home',
cond: {
type: 'canRoute',
path: '/',
exact: true
},
},
{
target: 'authenticated.account',
cond: {
type: 'canRoute',
path: '/account'
}
},
{
target: 'authenticated.test',
cond: {
type: 'canRoute',
path: '/tests',
exact: true
}
},
{
target: 'authenticated.test.details',
cond: {
type: 'canRoute',
path: '/tests/:testId',
},
},
],
ROUTED: {
actions: console.log
}
},
}, {
guards: {
isNotAuthenticated: ctx => !ctx.authenticated,
isAuthenticated: ctx => ctx.authenticated,
canRoute: (_, event, { cond }) => event.path === cond.path
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment