Skip to content

Commit 10f7314

Browse files
authored
Merge pull request #192 from rlaffers/migration-internal-external-transitions
Update the migration guide about internal/external transitions
2 parents 5416a9b + a5559bf commit 10f7314

File tree

1 file changed

+186
-0
lines changed

1 file changed

+186
-0
lines changed

versioned_docs/version-5/migration.mdx

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,192 @@ const machine = createMachine({
649649
</TabItem>
650650
</Tabs>
651651

652+
### Transitions are internal by default, not external
653+
654+
:::breakingchange
655+
656+
Breaking change
657+
658+
:::
659+
660+
All transitions are implicitly internal. This change is relevant for transitions defined on compound state nodes with `entry` or `exit` actions, invoked actors, or delayed transitions (`after`). If you relied on implicit re-entering of a compound state node, use `reenter: true`:
661+
662+
<Tabs>
663+
<TabItem value="v5" label="XState v5 beta">
664+
665+
```ts
666+
//
667+
const machine = createMachine({
668+
// ...
669+
states: {
670+
compoundState: {
671+
entry: 'someAction',
672+
on: {
673+
someEvent: {
674+
target: 'compoundState.childState',
675+
// Reenters the `compoundState` state,
676+
// just like an external transition
677+
reenter: true,
678+
},
679+
},
680+
initial: 'childState',
681+
states: {
682+
childState: {},
683+
},
684+
},
685+
},
686+
})
687+
```
688+
689+
</TabItem>
690+
691+
<TabItem value="v4" label="XState v4">
692+
693+
```ts
694+
// ❌ DEPRECATED
695+
const machine = createMachine({
696+
// ...
697+
states: {
698+
compoundState: {
699+
entry: 'someAction',
700+
on: {
701+
someEvent: {
702+
// implicitly external
703+
target: 'compoundState.childState', // non-relative target
704+
},
705+
},
706+
initial: 'childState',
707+
states: {
708+
childState: {},
709+
},
710+
},
711+
},
712+
})
713+
```
714+
715+
</TabItem>
716+
</Tabs>
717+
718+
<Tabs>
719+
<TabItem value="v5" label="XState v5 beta">
720+
721+
```ts
722+
//
723+
const machine = createMachine({
724+
// ...
725+
states: {
726+
compoundState: {
727+
after: {
728+
1000: {
729+
target: 'compoundState.childState',
730+
reenter: true, // make it external explicitly!
731+
}
732+
},
733+
initial: 'childState',
734+
states: {
735+
childState: {},
736+
},
737+
},
738+
},
739+
})
740+
```
741+
742+
</TabItem>
743+
744+
<TabItem value="v4" label="XState v4">
745+
746+
```ts
747+
// ❌ DEPRECATED
748+
const machine = createMachine({
749+
// ...
750+
states: {
751+
compoundState: {
752+
after: {
753+
1000: {
754+
// implicitly external
755+
target: 'compoundState.childState', // non-relative target
756+
}
757+
},
758+
initial: 'childState',
759+
states: {
760+
childState: {},
761+
},
762+
},
763+
},
764+
})
765+
```
766+
767+
</TabItem>
768+
</Tabs>
769+
770+
### Child state nodes are always re-entered
771+
772+
:::breakingchange
773+
774+
Breaking change
775+
776+
:::
777+
778+
Child state nodes are always re-entered when they are targeted by transitions (both external and **internal**) defined on compound state nodes. This change is relevant only if a child state node has `entry` or `exit` actions, invoked actors, or delayed transitions (`after`). Add a `stateIn` guard to prevent undesirable re-entry of the child state:
779+
780+
<Tabs>
781+
<TabItem value="v5" label="XState v5 beta">
782+
783+
```ts
784+
//
785+
786+
const machine = createMachine({
787+
// ...
788+
states: {
789+
compoundState: {
790+
on: {
791+
someEvent: {
792+
guard: not(stateIn({ compoundState: 'childState' }),
793+
target: '.childState',
794+
},
795+
},
796+
initial: 'childState',
797+
states: {
798+
childState: {
799+
entry: 'someAction',
800+
},
801+
},
802+
},
803+
},
804+
})
805+
```
806+
807+
</TabItem>
808+
809+
<TabItem value="v4" label="XState v4">
810+
811+
```ts
812+
// ❌ DEPRECATED
813+
814+
const machine = createMachine({
815+
// ...
816+
states: {
817+
compoundState: {
818+
on: {
819+
someEvent: {
820+
target: '.childState', // implicitly internal, childState not re-entered
821+
},
822+
},
823+
initial: 'childState',
824+
states: {
825+
childState: {
826+
entry: 'someAction',
827+
},
828+
},
829+
},
830+
},
831+
})
832+
```
833+
834+
</TabItem>
835+
836+
</Tabs>
837+
652838
### Use `stateIn()` to validate state transitions, not `in`
653839
654840
:::breakingchange

0 commit comments

Comments
 (0)