Skip to content

Commit e56856c

Browse files
authored
Merge pull request #170 from statelyai/davidkpiano/update-migration-guide-callbacks
Add changes to `fromCallback`
2 parents eb0d5db + 8b572c4 commit e56856c

File tree

3 files changed

+40
-40
lines changed

3 files changed

+40
-40
lines changed

blog/2023-05-25-announcing-xstate-v5-beta/index.mdx

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ One of the biggest items of feedback we’ve received about XState is that altho
3333
- **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:
3434

3535
```ts
36-
import { createMachine, interpret, assign } from "xstate";
36+
import { createMachine, interpret, assign } from 'xstate';
3737

3838
const counterMachine = createMachine({
39-
id: "counter",
39+
id: 'counter',
4040
context: {
4141
count: 0,
4242
},
@@ -54,9 +54,9 @@ const counterActor = interpret(counterMachine);
5454
counterActor.subscribe((state) => console.log(state.context.count));
5555
counterActor.start();
5656

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
6060
```
6161

6262
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 {
7474
fromEventObservable,
7575
fromCallback,
7676
createMachine,
77-
} from "xstate";
78-
import { interval, fromEvent } from "rxjs";
77+
} from 'xstate';
78+
import { interval, fromEvent } from 'rxjs';
7979

8080
// Promise logic
81-
const promiseLogic = fromPromise(() => fetch("https://api.example.com/users"));
81+
const promiseLogic = fromPromise(() => fetch('https://api.example.com/users'));
8282

8383
// Transition logic
8484
const transitionLogic = fromTransition(
8585
(state, event) => {
86-
if (event.type === "increment") {
86+
if (event.type === 'increment') {
8787
return { ...state, count: state.count + 1 };
88-
} else if (event.type === "decrement") {
88+
} else if (event.type === 'decrement') {
8989
return { ...state, count: state.count - 1 };
9090
}
9191

9292
return state;
9393
},
94-
{ count: 0 }
94+
{ count: 0 },
9595
);
9696

9797
// Observable logic
9898
const observableLogic = fromObservable(() => interval(1000));
9999

100100
// Event observable logic
101101
const eventObservableLogic = fromEventObservable(() =>
102-
fromEvent(window, "resize")
102+
fromEvent(window, 'resize'),
103103
);
104104

105105
// Callback logic
106-
const callbackLogic = fromCallback((sendBack) => {
106+
const callbackLogic = fromCallback(({ sendBack }) => {
107107
const handler = (ev) => {
108108
sendBack(ev);
109109
};
110110

111-
window.addEventListener("resize", handler);
111+
window.addEventListener('resize', handler);
112112

113113
return () => {
114-
window.removeEventListener("resize", handler);
114+
window.removeEventListener('resize', handler);
115115
};
116116
});
117117

@@ -154,8 +154,8 @@ In the following example, the state of the `mainActor` will be persisted, as wel
154154
```ts
155155
const machine = createMachine({
156156
invoke: {
157-
src: "counter",
158-
id: "someCounter",
157+
src: 'counter',
158+
id: 'someCounter',
159159
},
160160
// ...
161161
});
@@ -187,13 +187,13 @@ In XState v5 beta, calling `interpret(...)` to create a root actor will also cre
187187
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`:
188188

189189
```ts
190-
import { notifierMachine } from "../notifierMachine";
191-
import { shippingMachine } from "../shippingMachine";
190+
import { notifierMachine } from '../notifierMachine';
191+
import { shippingMachine } from '../shippingMachine';
192192

193193
const checkoutMachine = createMachine({
194194
invoke: {
195195
src: notifierMachine,
196-
systemId: "notifier",
196+
systemId: 'notifier',
197197
},
198198
// ...
199199
states: {
@@ -216,10 +216,10 @@ Now, any actor within the `checkoutActor` system can access the notifier actor b
216216
const shippingMachine = createMachine({
217217
// ...
218218
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',
223223
}),
224224
},
225225
},
@@ -248,7 +248,7 @@ const greetingMachine = createMachine({
248248

249249
const greetingActor = interpret(greetingMachine, {
250250
input: {
251-
name: "David",
251+
name: 'David',
252252
},
253253
});
254254
```
@@ -257,7 +257,7 @@ Furthermore, this works for any actor logic, not just state machines:
257257

258258
```ts
259259
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()),
261261
);
262262

263263
const promiseActor = interpret(promiseLogic, {
@@ -300,12 +300,12 @@ In the unified argument object, there is a `self` property that references the a
300300
```ts
301301
const pingMachine = createMachine({
302302
invoke: {
303-
src: "pong",
304-
id: "pong",
303+
src: 'pong',
304+
id: 'pong',
305305
},
306306
on: {
307307
ping: {
308-
actions: sendTo("pong", ({ self }) => ({ type: "ping", sender: self })),
308+
actions: sendTo('pong', ({ self }) => ({ type: 'ping', sender: self })),
309309
},
310310
},
311311
});
@@ -315,7 +315,7 @@ const pingMachine = createMachine({
315315
const pongMachine = createMachine({
316316
on: {
317317
ping: {
318-
actions: sendTo(({ event }) => event.sender, { type: "pong" }),
318+
actions: sendTo(({ event }) => event.sender, { type: 'pong' }),
319319
},
320320
},
321321
});
@@ -326,7 +326,7 @@ const pongMachine = createMachine({
326326
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)`:
327327

328328
```ts
329-
import { createMachine, and, not } from "xstate";
329+
import { createMachine, and, not } from 'xstate';
330330

331331
const userMachine = createMachine(
332332
{
@@ -335,17 +335,17 @@ const userMachine = createMachine(
335335
doSomething: {
336336
// Higher-order guard
337337
// Renamed from "cond" (v4) -> "guard" (v5)
338-
guard: and(["isAuthenticated", "isAdmin", not("isBanned")]),
338+
guard: and(['isAuthenticated', 'isAdmin', not('isBanned')]),
339339
},
340340
},
341341
},
342342
{
343343
guards: {
344344
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',
347347
},
348-
}
348+
},
349349
);
350350
```
351351

@@ -373,8 +373,8 @@ const machine = createMachine({
373373
on: {
374374
// Will handle any event that starts with "pointer.":
375375
// "pointer.down", "pointer.up", "pointer.move", etc.
376-
"pointer.*": {
377-
actions: "logPointerEvent",
376+
'pointer.*': {
377+
actions: 'logPointerEvent',
378378
},
379379
},
380380
});

versioned_docs/version-5/actors.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,13 @@ canvasActor.start();
322322

323323
## Callback actors
324324

325-
Callback actor logic is described by a callback function that receives a `sendBack` function and a `receive` function. Actors created from callback logic (“callback actors”) can:
325+
Callback actor logic is described by a callback function that receives a single object argument that includes a `sendBack(event)` function and a `receive(event => ...)` function. Actors created from callback logic (“callback actors”) can:
326326

327327
- Receive events via the `receive` function
328328
- Send events to the parent actor via the `sendBack` function
329329

330330
```ts
331-
const callbackLogic = fromCallback((sendBack, receive) => {
331+
const callbackLogic = fromCallback(({ sendBack, receive }) => {
332332
let lockStatus = 'unlocked';
333333

334334
const handler = (event) => {

versioned_docs/version-5/migration.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ import { fromCallback, createMachine } from 'xstate';
769769

770770
const machine = createMachine({
771771
invoke: {
772-
src: fromCallback((sendBack, receive, { input }) => {
772+
src: fromCallback(({ sendBack, receive, input }) => {
773773
// ...
774774
}),
775775
input: ({ context, event }) => ({

0 commit comments

Comments
 (0)