@@ -33,10 +33,10 @@ One of the biggest items of feedback we’ve received about XState is that altho
33
33
- **From zero to “hello world” as quickly as possible**. Our goal with XState v5 and the [updated documentation (work in progress)](https://stately.ai/docs/xstate-v5) is to make developers productive with XState quickly. A simple, complete counter example in XState looks like this:
34
34
35
35
```ts
36
- import { createMachine , interpret , assign } from " xstate" ;
36
+ import { createMachine , interpret , assign } from ' xstate' ;
37
37
38
38
const counterMachine = createMachine({
39
- id: " counter" ,
39
+ id: ' counter' ,
40
40
context: {
41
41
count : 0 ,
42
42
} ,
@@ -54,9 +54,9 @@ const counterActor = interpret(counterMachine);
54
54
counterActor.subscribe((state) => console.log(state.context.count));
55
55
counterActor.start();
56
56
57
- counterActor.send({ type: " increment" }); // logs 1
58
- counterActor.send({ type: " increment" }); // logs 2
59
- counterActor.send({ type: " decrement" }); // logs 1
57
+ counterActor.send({ type: ' increment' }); // logs 1
58
+ counterActor.send({ type: ' increment' }); // logs 2
59
+ counterActor.send({ type: ' decrement' }); // logs 1
60
60
```
61
61
62
62
This functionality is already capable of meeting the majority of state management needs for most applications. If you require more advanced use cases, have no fear - XState v5 beta has got you covered.
@@ -74,44 +74,44 @@ import {
74
74
fromEventObservable ,
75
75
fromCallback ,
76
76
createMachine ,
77
- } from " xstate" ;
78
- import { interval , fromEvent } from " rxjs" ;
77
+ } from ' xstate' ;
78
+ import { interval , fromEvent } from ' rxjs' ;
79
79
80
80
// Promise logic
81
- const promiseLogic = fromPromise(() => fetch(" https://api.example.com/users" ));
81
+ const promiseLogic = fromPromise(() => fetch(' https://api.example.com/users' ));
82
82
83
83
// Transition logic
84
84
const transitionLogic = fromTransition(
85
85
(state, event) => {
86
- if (event .type === " increment" ) {
86
+ if (event .type === ' increment' ) {
87
87
return { ... state , count : state .count + 1 };
88
- } else if (event .type === " decrement" ) {
88
+ } else if (event .type === ' decrement' ) {
89
89
return { ... state , count : state .count - 1 };
90
90
}
91
91
92
92
return state ;
93
93
} ,
94
- { count : 0 }
94
+ { count : 0 } ,
95
95
);
96
96
97
97
// Observable logic
98
98
const observableLogic = fromObservable(() => interval(1000));
99
99
100
100
// Event observable logic
101
101
const eventObservableLogic = fromEventObservable(() =>
102
- fromEvent(window, " resize" )
102
+ fromEvent(window, ' resize' ),
103
103
);
104
104
105
105
// Callback logic
106
- const callbackLogic = fromCallback((sendBack) => {
106
+ const callbackLogic = fromCallback(({ sendBack } ) => {
107
107
const handler = (ev ) => {
108
108
sendBack (ev );
109
109
};
110
110
111
- window .addEventListener (" resize" , handler );
111
+ window .addEventListener (' resize' , handler );
112
112
113
113
return () => {
114
- window .removeEventListener (" resize" , handler );
114
+ window .removeEventListener (' resize' , handler );
115
115
};
116
116
} );
117
117
@@ -154,8 +154,8 @@ In the following example, the state of the `mainActor` will be persisted, as wel
154
154
```ts
155
155
const machine = createMachine({
156
156
invoke: {
157
- src : " counter" ,
158
- id : " someCounter" ,
157
+ src : ' counter' ,
158
+ id : ' someCounter' ,
159
159
} ,
160
160
// ...
161
161
});
@@ -187,13 +187,13 @@ In XState v5 beta, calling `interpret(...)` to create a root actor will also cre
187
187
For example, let’s say you have a `checkoutMachine` that orchestrates the state of an online shop. If you want a notifier actor to be available to any machines spawned anywhere within the `checkoutMachine` system, you can register it by providing a `systemId`:
188
188
189
189
```ts
190
- import { notifierMachine } from " ../notifierMachine" ;
191
- import { shippingMachine } from " ../shippingMachine" ;
190
+ import { notifierMachine } from ' ../notifierMachine' ;
191
+ import { shippingMachine } from ' ../shippingMachine' ;
192
192
193
193
const checkoutMachine = createMachine({
194
194
invoke: {
195
195
src : notifierMachine ,
196
- systemId : " notifier" ,
196
+ systemId : ' notifier' ,
197
197
} ,
198
198
// ...
199
199
states: {
@@ -216,10 +216,10 @@ Now, any actor within the `checkoutActor` system can access the notifier actor b
216
216
const shippingMachine = createMachine({
217
217
// ...
218
218
on: {
219
- " address.updated" : {
220
- actions: sendTo (({ system }) => system .get (" notifier" ), {
221
- type: " notify" ,
222
- message: " Shipping address updated" ,
219
+ ' address.updated' : {
220
+ actions: sendTo (({ system }) => system .get (' notifier' ), {
221
+ type: ' notify' ,
222
+ message: ' Shipping address updated' ,
223
223
}),
224
224
},
225
225
} ,
@@ -248,7 +248,7 @@ const greetingMachine = createMachine({
248
248
249
249
const greetingActor = interpret(greetingMachine, {
250
250
input : {
251
- name: " David" ,
251
+ name: ' David' ,
252
252
},
253
253
} );
254
254
```
@@ -257,7 +257,7 @@ Furthermore, this works for any actor logic, not just state machines:
257
257
258
258
```ts
259
259
const promiseLogic = fromPromise(({ input }) =>
260
- fetch(`https://api.example.com/users/${input.id}`).then((res) => res.json())
260
+ fetch(`https://api.example.com/users/${input.id}`).then((res) => res.json()),
261
261
);
262
262
263
263
const promiseActor = interpret(promiseLogic, {
@@ -300,12 +300,12 @@ In the unified argument object, there is a `self` property that references the a
300
300
``` ts
301
301
const pingMachine = createMachine ({
302
302
invoke: {
303
- src: " pong" ,
304
- id: " pong" ,
303
+ src: ' pong' ,
304
+ id: ' pong' ,
305
305
},
306
306
on: {
307
307
ping: {
308
- actions: sendTo (" pong" , ({ self }) => ({ type: " ping" , sender: self })),
308
+ actions: sendTo (' pong' , ({ self }) => ({ type: ' ping' , sender: self })),
309
309
},
310
310
},
311
311
});
@@ -315,7 +315,7 @@ const pingMachine = createMachine({
315
315
const pongMachine = createMachine ({
316
316
on: {
317
317
ping: {
318
- actions: sendTo (({ event }) => event .sender , { type: " pong" }),
318
+ actions: sendTo (({ event }) => event .sender , { type: ' pong' }),
319
319
},
320
320
},
321
321
});
@@ -326,7 +326,7 @@ const pongMachine = createMachine({
326
326
In XState v4, guards were simple functions on the ` .cond ` transition property that returned ` true ` or ` false ` to determine if a transition would be taken. To negate a guard or combine guards, you had to create a new guard, which resulted in duplication or redundant code. In XState v5 beta, you can now use higher-order guards, which are functions that take in guards (referenced and/or inline) and return a guard function. There are 3 built-in higher-order guard functions: ` and([...guards]) ` , ` or([...guards]) ` , and ` not(guard) ` :
327
327
328
328
``` ts
329
- import { createMachine , and , not } from " xstate" ;
329
+ import { createMachine , and , not } from ' xstate' ;
330
330
331
331
const userMachine = createMachine (
332
332
{
@@ -335,17 +335,17 @@ const userMachine = createMachine(
335
335
doSomething: {
336
336
// Higher-order guard
337
337
// Renamed from "cond" (v4) -> "guard" (v5)
338
- guard: and ([" isAuthenticated" , " isAdmin" , not (" isBanned" )]),
338
+ guard: and ([' isAuthenticated' , ' isAdmin' , not (' isBanned' )]),
339
339
},
340
340
},
341
341
},
342
342
{
343
343
guards: {
344
344
isAuthenticated : ({ context }) => context .user !== undefined ,
345
- isAdmin : ({ context }) => context .user .role === " admin" ,
346
- isBanned : ({ context }) => context .user .status === " banned" ,
345
+ isAdmin : ({ context }) => context .user .role === ' admin' ,
346
+ isBanned : ({ context }) => context .user .status === ' banned' ,
347
347
},
348
- }
348
+ },
349
349
);
350
350
```
351
351
@@ -373,8 +373,8 @@ const machine = createMachine({
373
373
on: {
374
374
// Will handle any event that starts with "pointer.":
375
375
// "pointer.down", "pointer.up", "pointer.move", etc.
376
- " pointer.*" : {
377
- actions: " logPointerEvent" ,
376
+ ' pointer.*' : {
377
+ actions: ' logPointerEvent' ,
378
378
},
379
379
},
380
380
});
0 commit comments