Is it ok to use "external deps" in guards?
E.g.
{
guards: {
hasAccessToken: (ctx, event) =>
ctx.foo && event.bar && !!localStorage.getItem("token")
}
}
IMHO it's OK - while it's maybe not ideal I usually try to apply "don't overcomplicate things" strategy. Without this you'd have to somehow check externally for localStorage changes and send events to the machine which in turn would update its context. While this is not impossible I believe the return of such investment is not worth it in majority of cases.
This will "work" but when it comes to testing, analysis, simulation, you might have problems. In general, guards should be pure and this function is 馃毇 not pure 馃毇.
So how can we make it pure? Use context.
const machine = Machine({
// ...
context: {
token: null
},
// ...
}, {
guards: {
hasAccessToken: ctx => !!ctx.token
}
});
const machineWithToken = machine.withConfig({ token: localStorage.get('token') });
Now it can be modeled in a more flexible, testable way.
Keep in mind that this simplified solution might fall short when a localStorage value can get changed by another browser tab.
If this is irrelevant for the particular problem I would of course also put it into machine's initial context.
Most helpful comment
Keep in mind that this simplified solution might fall short when a localStorage value can get changed by another browser tab.
If this is irrelevant for the particular problem I would of course also put it into machine's initial context.