Skip to content

Commit beb7c41

Browse files
committedNov 12, 2024·
Merge branch 'main' into gavin/add-webinargeek-case-study
2 parents 2474d4a + d0558ed commit beb7c41

File tree

1 file changed

+149
-119
lines changed

1 file changed

+149
-119
lines changed
 

‎docs/actions.mdx

+149-119
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ Actions can also be on a state’s `entry` or `exit`, also as a single action or
1515
```ts
1616
import { setup } from 'xstate';
1717

18+
function trackResponse(response: string) {
19+
// ...
20+
}
21+
1822
const feedbackMachine = setup({
1923
actions: {
20-
track: (_, params: unknown) => {
21-
track(params);
24+
track: (_, params: { response: string }) => {
25+
trackResponse(params.response);
2226
// Tracks { response: 'good' }
2327
},
2428
showConfetti: () => {
@@ -62,7 +66,10 @@ Entry actions are actions that occur on any transition that enters a state node.
6266

6367
Entry and exit actions are defined using the `entry: [...]` and `exit: [...]` attributes on a state node. You can fire multiple entry and exit actions on a state. Top-level final states cannot have exit actions, since the machine is stopped and no further transitions can occur.
6468

65-
<EmbedMachine embedURL="https://stately.ai/registry/editor/embed/c447d996-cef1-421d-a422-8be695668764?mode=design&machineId=f46674a5-4da3-4aca-9900-17c6ef471f50" title="Feedback form"/>
69+
<EmbedMachine
70+
embedURL="https://stately.ai/registry/editor/embed/c447d996-cef1-421d-a422-8be695668764?mode=design&machineId=f46674a5-4da3-4aca-9900-17c6ef471f50"
71+
title="Feedback form"
72+
/>
6673

6774
## Action objects
6875

@@ -76,8 +83,10 @@ import { setup } from 'xstate';
7683

7784
const feedbackMachine = setup({
7885
actions: {
79-
track: (_, params: unknown) => {/* ... */}
80-
}
86+
track: (_, params: { response: string }) => {
87+
/* ... */
88+
},
89+
},
8190
}).createMachine({
8291
// ...
8392
states: {
@@ -113,20 +122,22 @@ const feedbackMachine = setup({
113122
actions: {
114123
logInitialRating: (_, params: { initialRating: number }) => {
115124
// ...
116-
}
117-
}
125+
},
126+
},
118127
}).createMachine({
119128
context: {
120-
initialRating: 3
129+
initialRating: 3,
121130
},
122-
entry: [{
123-
type: 'logInitialRating',
124-
// highlight-start
125-
params: ({ context }) => ({
126-
initialRating: context.initialRating
127-
})
128-
// highlight-end
129-
}]
131+
entry: [
132+
{
133+
type: 'logInitialRating',
134+
// highlight-start
135+
params: ({ context }) => ({
136+
initialRating: context.initialRating,
137+
}),
138+
// highlight-end
139+
},
140+
],
130141
});
131142
```
132143

@@ -142,17 +153,19 @@ function logInitialRating(_, params: { initialRating: number }) {
142153
// highlight-end
143154

144155
const feedbackMachine = setup({
145-
actions: { logInitialRating }
156+
actions: { logInitialRating },
146157
}).createMachine({
147158
context: { initialRating: 3 },
148-
entry: [{
149-
type: 'logInitialRating',
150-
// highlight-start
151-
params: ({ context }) => ({
152-
initialRating: context.initialRating
153-
})
154-
// highlight-end
155-
}]
159+
entry: [
160+
{
161+
type: 'logInitialRating',
162+
// highlight-start
163+
params: ({ context }) => ({
164+
initialRating: context.initialRating,
165+
}),
166+
// highlight-end
167+
},
168+
],
156169
});
157170
```
158171

@@ -187,18 +200,16 @@ import { setup } from 'xstate';
187200
const feedbackMachine = setup({
188201
// highlight-start
189202
actions: {
190-
track: ({ context, event }, params) => {
203+
track: (_, params: { msg: string }) => {
191204
// Action implementation
192205
// ...
193206
},
194-
}
195-
// highlight-end
196-
}).createMachine(
197-
{
198-
// Machine config
199-
entry: [{ type: 'track', params: { msg: 'entered' }}]
200207
},
201-
);
208+
// highlight-end
209+
}).createMachine({
210+
// Machine config
211+
entry: [{ type: 'track', params: { msg: 'entered' } }],
212+
});
202213
```
203214

204215
You can also provide action implementations to override existing actions in the `machine.provide(...)` method, which creates a new machine with the same config but with the provided implementations:
@@ -236,7 +247,7 @@ const machine = createMachine({
236247
// This action creator only returns an action object
237248
// like { type: 'xstate.assign', ... }
238249
assign({ count: context.count + 1 });
239-
}
250+
},
240251
// highlight-end
241252
});
242253

@@ -245,8 +256,8 @@ const machine = createMachine({
245256
context: { count: 0 },
246257
// highlight-start
247258
entry: assign({
248-
count: ({ context }) => context.count + 1
249-
})
259+
count: ({ context }) => context.count + 1,
260+
}),
250261
// highlight-end
251262
});
252263

@@ -256,9 +267,9 @@ const machine = createMachine({
256267
// highlight-start
257268
entry: enqueueActions(({ context, enqueue }) => {
258269
enqueue.assign({
259-
count: context.count + 1
270+
count: context.count + 1,
260271
});
261-
})
272+
}),
262273
// highlight-end
263274
});
264275
```
@@ -276,8 +287,8 @@ import { setup } from 'xstate';
276287

277288
const countMachine = setup({
278289
types: {
279-
events: {} as { type: 'increment'; value: number }
280-
}
290+
events: {} as { type: 'increment'; value: number },
291+
},
281292
}).createMachine({
282293
context: {
283294
count: 0,
@@ -314,8 +325,8 @@ import { setup } from 'xstate';
314325

315326
const countMachine = setup({
316327
types: {
317-
events: {} as { type: 'increment'; value: number }
318-
}
328+
events: {} as { type: 'increment'; value: number },
329+
},
319330
}).createMachine({
320331
context: {
321332
count: 0,
@@ -373,14 +384,13 @@ const machine = createMachine({
373384
entry: raise(({ context, event }) => ({
374385
type: 'dynamicEvent',
375386
data: context.someValue,
376-
}))
387+
})),
377388
// highlight-end
378389
});
379390
```
380391

381392
Events can also be raised with a delay, which will not place them in the internal event queue, since they will not be immediately processed:
382393

383-
384394
```ts
385395
import { createMachine, raise } from 'xstate';
386396

@@ -496,18 +506,17 @@ import { createMachine, sendTo } from 'xstate';
496506

497507
const childMachine = createMachine({
498508
context: ({ input }) => ({
499-
parentRef: input.parentRef
509+
parentRef: input.parentRef,
500510
}),
501511
on: {
502512
someEvent: {
503513
// highlight-start
504-
actions: sendTo(
505-
({ context }) => context.parentRef,
506-
{ type: 'tellParentSomething' }
507-
),
514+
actions: sendTo(({ context }) => context.parentRef, {
515+
type: 'tellParentSomething',
516+
}),
508517
// highlight-end
509-
}
510-
}
518+
},
519+
},
511520
});
512521

513522
const parentMachine = createMachine({
@@ -517,17 +526,17 @@ const parentMachine = createMachine({
517526
src: childMachine,
518527
// highlight-start
519528
input: ({ self }) => ({
520-
parentRef: self
521-
})
529+
parentRef: self,
530+
}),
522531
// highlight-end
523532
},
524533
on: {
525534
tellParentSomething: {
526535
actions: () => {
527536
console.log('Child actor told parent something');
528-
}
529-
}
530-
}
537+
},
538+
},
539+
},
531540
});
532541

533542
const parentActor = createActor(parentMachine);
@@ -537,46 +546,69 @@ parentActor.start();
537546

538547
</details>
539548

540-
:::
549+
<details>
550+
<summary>Example using input (TypeScript):</summary>
541551

542552
```ts
543-
import { createMachine, sendParent } from 'xstate';
553+
import { ActorRef, createActor, log, sendTo, setup, Snapshot } from 'xstate';
544554

545-
const childMachine = createMachine({
546-
on: {
547-
someEvent: {
548-
// highlight-start
549-
actions: sendParent({ type: 'tellParentSomething' }),
550-
// highlight-end
551-
}
552-
}
555+
// highlight-start
556+
type ChildEvent = {
557+
type: 'tellParentSomething';
558+
data?: string;
559+
};
560+
type ParentActor = ActorRef<Snapshot<unknown>, ChildEvent>;
561+
// highlight-end
562+
563+
const childMachine = setup({
564+
types: {
565+
context: {} as {
566+
parentRef: ParentActor
567+
},
568+
input: {} as {
569+
parentRef: ParentActor;
570+
},
571+
},
572+
}).createMachine({
573+
context: ({ input: { parentRef } }) => ({parentRef}),
574+
// highlight-start
575+
entry: sendTo(({ context }) => context.parentRef, {
576+
type: 'tellParentSomething',
577+
data: 'Hi parent!',
578+
}),
579+
// highlight-end
553580
});
554581

555-
const parentMachine = createMachine({
556-
// ...
582+
export const parent = setup({
583+
actors: { child: childMachine },
584+
}).createMachine({
585+
// highlight-start
557586
invoke: {
558-
id: 'child',
559-
src: childMachine
587+
src: 'child',
588+
input: ({ self }) => ({
589+
parentRef: self,
590+
}),
560591
},
592+
// highlight-end
561593
on: {
562594
tellParentSomething: {
563-
actions: () => {
564-
console.log('Child actor told parent something');
565-
}
566-
}
567-
}
595+
actions: log( ({event:{data}})=> `Child actor says "${data}"`),
596+
},
597+
},
568598
});
569599

570-
const parentActor = createActor(parentMachine);
571-
572-
parentActor.start();
600+
createActor(parent).start();
573601
```
602+
</details>
603+
604+
:::
574605

575606
## Enqueue actions
576607

577608
The `enqueueActions(...)` action creator is a higher-level action that enqueues actions to be executed sequentially, without actually executing any of the actions. It takes a callback that receives the `context`, `event` as well as `enqueue` and `check` functions:
578609

579610
- The `enqueue(...)` function is used to enqueue an action. It takes an action object or action function:
611+
580612
```ts
581613
actions: enqueueActions(({ enqueue }) => {
582614
// Enqueue an action object
@@ -587,15 +619,16 @@ The `enqueueActions(...)` action creator is a higher-level action that enqueues
587619

588620
// Enqueue a simple action with no params
589621
enqueue('doSomething');
590-
})
622+
});
591623
```
624+
592625
- The `check(...)` function is used to conditionally enqueue an action. It takes a guard object or a guard function and returns a boolean that represents whether the guard evaluates to `true`:
593626
```ts
594627
actions: enqueueActions(({ enqueue, check }) => {
595628
if (check({ type: 'everythingLooksGood' })) {
596629
enqueue('doSomething');
597630
}
598-
})
631+
});
599632
```
600633
- There are also helper methods on `enqueue` for enqueueing built-in actions:
601634
- `enqueue.assign(...)`: Enqueues an `assign(...)` action
@@ -613,7 +646,7 @@ const machine = createMachine({
613646
entry: enqueueActions(({ context, event, enqueue, check }) => {
614647
// assign action
615648
enqueue.assign({
616-
count: context.count + 1
649+
count: context.count + 1,
617650
});
618651

619652
// Conditional actions (replaces choose(...))
@@ -637,7 +670,7 @@ const machine = createMachine({
637670
}
638671

639672
// no return
640-
})
673+
}),
641674
});
642675
```
643676

@@ -656,15 +689,15 @@ const machine = setup({
656689
// highlight-end
657690
greet: (_, params: { name: string }) => {
658691
console.log(`Hello ${params.name}!`);
659-
}
660-
}
692+
},
693+
},
661694
}).createMachine({
662695
// ...
663696
// highlight-start
664697
entry: {
665698
type: 'doThings',
666-
params: { name: 'World' }
667-
}
699+
params: { name: 'World' },
700+
},
668701
// highlight-end
669702
});
670703
```
@@ -693,7 +726,6 @@ You can create state machines with the `log(...)` action in our drag-and-drop St
693726

694727
:::
695728

696-
697729
## Cancel action
698730

699731
The `cancel(...)` action cancels a delayed `sendTo(...)` or `raise(...)` action by their IDs:
@@ -779,7 +811,6 @@ const countMachine = createMachine({
779811
For simple actions, you can specify an action string instead of an action object. Though we prefer using objects for consistency.
780812

781813
```ts
782-
783814
import { createMachine } from 'xstate';
784815

785816
const feedbackMachine = createMachine({
@@ -797,14 +828,13 @@ const feedbackMachine = createMachine({
797828
},
798829
},
799830
});
800-
801831
```
802832

803833
## Actions and TypeScript
804834

805835
:::typescript
806836

807-
**XState v5 requires TypeScript version 5.0 or greater.**
837+
**XState v5 requires TypeScript version 5.0 or greater.**
808838

809839
For best results, use the latest TypeScript version. [Read more about XState and TypeScript](typescript.mdx)
810840

@@ -825,15 +855,15 @@ const machine = setup({
825855
},
826856
increment: (_, params: { value: number }) => {
827857
// ...
828-
}
829-
}
858+
},
859+
},
830860
// highlight-end
831861
}).createMachine({
832862
// ...
833863
entry: [
834864
{ type: 'track', params: { response: 'good' } },
835865
{ type: 'increment', params: { value: 1 } },
836-
]
866+
],
837867
});
838868
```
839869

@@ -878,11 +908,11 @@ const machine = createMachine({
878908
states: {
879909
start: {
880910
// highlight-start
881-
entry: [{ type:'startEntryAction' }],
882-
exit: [{ type:'startExitAction' }],
911+
entry: [{ type: 'startEntryAction' }],
912+
exit: [{ type: 'startExitAction' }],
883913
// highlight-end
884-
}
885-
}
914+
},
915+
},
886916
});
887917
```
888918

@@ -899,9 +929,9 @@ const machine = createMachine({
899929
{ type: 'doSomething' },
900930
{ type: 'doSomethingElse' },
901931
// highlight-end
902-
]
903-
}
904-
}
932+
],
933+
},
934+
},
905935
});
906936
```
907937

@@ -917,11 +947,11 @@ const machine = createMachine({
917947
// highlight-start
918948
({ context, event }) => {
919949
console.log(context, event);
920-
}
950+
},
921951
// highlight-end
922-
]
923-
}
924-
}
952+
],
953+
},
954+
},
925955
});
926956
```
927957

@@ -932,20 +962,20 @@ import { setup } from 'xstate';
932962

933963
const someAction = () => {
934964
//...
935-
}
965+
};
936966

937967
const machine = setup({
938968
actions: {
939-
someAction
940-
}
969+
someAction,
970+
},
941971
}).createMachine({
942972
entry: [
943973
// highlight-start
944-
{ type: 'someAction' }
974+
{ type: 'someAction' },
945975
// highlight-end
946976
],
947977
// ...
948-
})
978+
});
949979
```
950980

951981
### Cheatsheet: providing actions
@@ -955,20 +985,20 @@ import { setup } from 'xstate';
955985

956986
const someAction = () => {
957987
//...
958-
}
988+
};
959989

960990
const machine = setup({
961991
actions: {
962-
someAction
963-
}
992+
someAction,
993+
},
964994
}).createMachine({
965995
// ...
966996
});
967997

968998
const modifiedMachine = machine.provide({
969999
someAction: () => {
9701000
// Overridden action implementation
971-
}
1001+
},
9721002
});
9731003
```
9741004

@@ -989,7 +1019,7 @@ const countMachine = createMachine({
9891019
actions: assign({
9901020
count: ({ context, event }) => {
9911021
return context.count + event.value;
992-
}
1022+
},
9931023
}),
9941024
// highlight-end
9951025
},
@@ -1011,7 +1041,7 @@ const countMachine = createMachine({
10111041
// highlight-start
10121042
actions: assign(({ context, event }) => {
10131043
return {
1014-
count: context.count + event.value
1044+
count: context.count + event.value,
10151045
};
10161046
}),
10171047
// highlight-end
@@ -1065,13 +1095,13 @@ const machine = createMachine({
10651095
}
10661096

10671097
enqueue.assign({
1068-
count: 0
1069-
})
1098+
count: 0,
1099+
});
10701100

10711101
enqueue.sendTo('someActor', { type: 'someEvent' });
10721102

1073-
enqueue.raise({ type: 'anEvent' })
1074-
})
1103+
enqueue.raise({ type: 'anEvent' });
1104+
}),
10751105
// highlight-end
10761106
});
10771107
```

0 commit comments

Comments
 (0)
Please sign in to comment.