Description
If an invoked machine has an eventless or transient transition defined, it is evaluated twice: first with the default context, and second with the context passed from the parent. This is changed from behaviour <4.11.0, where transient transitions were not evaluated before the context was passed. This is problematic where there are guards defined that rely on the passed context. In my case I had no default context on the child machine, so the guards threw exceptions because of the undefined context.
Expected Result
Transitions are only evaluated with the context passed from the parent.
Actual Result
Transitions are evaluated twice: once with the default (or undefined) context, then immediately after with the passed context.
Reproduction
https://codesandbox.io/s/sad-lake-3e0bh - switch to use a transient transition, then change back to 4.10.0 and see there is no longer an error.
Additional context
Version 4.11.0
Thanks for the report - I will take a look into it soon.
This has a simple (and almost necessary) workaround - if your machine expects anything in context, it _must_ have initial context defined.
In other words, add this:
const timerMachine = Machine({
id: "timer",
initial: "intitial",
+ context: {},
states: {
See here for the working example with 4.11: https://codesandbox.io/s/competent-raman-eno75?file=/src/index.js:248-343
I believe this is an actual bug and the proposed workaround is not sufficient.
This is caused by those lines:
https://github.com/davidkpiano/xstate/blob/8226700aab94031f66133c6518430786aab4780c/packages/core/src/Actor.ts#L52-L54
As we may see the .initialState of the invoked machine is being read and this leads to initial transient transitions being evaluated which in this case crash the program. But this could also lead to an incorrect state being assigned to that deferred actor as user has expressed a dependency on a custom .data but our implementation ignores it entirely here. And this, in turn, might, for example, cause incorrect state being rendered at first by @xstate/react.
Just to let you know - I might have a fix locally but I still need to write the appropriate test for it, which I plan to do tomorrow.
Most helpful comment
Thanks for the report - I will take a look into it soon.