When using a state machine with vue, I've noticed that reading part of the context in a component through useSelector or a computed wouldn't work without explicitly accessing the snapshot. Leading to weird edge cases where you'd have to console.log(snapshot.value) or add the snapshot in the template for it to be reactive.
Investigating further I tracked the root cause of the issue to the vue useSelector implementation.
Here are vue docs for reference : https://vuejs.org/api/reactivity-advanced.html#triggerref
The official stackblitz template is somehow not working for me, so here's a short code snippet that explains the issue :
// useMyMachine is a singleton to share the same actor accross multiple component.
// A.vue
cont { snpashot, actorRef } = toRefs(useMyMachine())
//This would not be reactive unless snapshot.value is accessed somewhere in a component.
const notWorkingDerivedState = useSelector(actorRef, (state) => state.context.someValue)
// B.vue
// This would work
const workingDerivedState = computed(() => {
if (snapshot.value.value) {
return useSelector(actorRef, (state) => state.context.someValue)
}
})
Expected result
useSelector should always return an up to date value.
Actual result
useSelector was returning an up to date value only if it was accessed manually.
Reproduction
Vue official template is not working
Additional context
The workaround for me was to re-implement all the export from vue-xstate locally. I'll make a PR shortly with the fix.
XState version
XState version 5
Description
When using a state machine with vue, I've noticed that reading part of the context in a component through useSelector or a computed wouldn't work without explicitly accessing the snapshot. Leading to weird edge cases where you'd have to
console.log(snapshot.value)
or add the snapshot in the template for it to be reactive. Investigating further I tracked the root cause of the issue to the vueuseSelector
implementation. Here are vue docs for reference : https://vuejs.org/api/reactivity-advanced.html#triggerrefThe official stackblitz template is somehow not working for me, so here's a short code snippet that explains the issue :
Expected result
useSelector
should always return an up to date value.Actual result
useSelector
was returning an up to date value only if it was accessed manually.Reproduction
Vue official template is not working
Additional context
The workaround for me was to re-implement all the export from vue-xstate locally. I'll make a PR shortly with the fix.