Skip to content

[v5] enqueueActions() (replaces pure() and choose())#4429

Merged
Andarist merged 21 commits intonextfrom
v5/createAction
Nov 30, 2023
Merged

[v5] enqueueActions() (replaces pure() and choose())#4429
Andarist merged 21 commits intonextfrom
v5/createAction

Conversation

@davidkpiano
Copy link
Member

@davidkpiano davidkpiano commented Nov 5, 2023

actions: enqueueActions(({ context, event, enqueue }) => {
  enqueue.assign({
    count: context.count + 1
  });

  // Conditional actions (replaces choose(...))
  if (event.someOption) {
    enqueue.sendTo('someActor', { type: 'blah', thing: context.thing });
    
    // other actions
    enqueue('namedAction');
    // with params
    enqueue({ type: 'greet', params: { message: 'hello' }});
  } else {
    // inline
    enqueue(() => console.log('hello'));
  }

  // no return
})

@davidkpiano davidkpiano requested a review from Andarist November 5, 2023 12:21
@changeset-bot
Copy link

changeset-bot bot commented Nov 5, 2023

🦋 Changeset detected

Latest commit: 25fdbf9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
xstate Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codesandbox-ci
Copy link

codesandbox-ci bot commented Nov 5, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 25fdbf9:

Sandbox Source
XState Example Template Configuration
XState React Template Configuration

Comment on lines +3034 to +3036
if (guard({ type: 'worstGuard' })) {
exec.action({ type: 'revealAnswer' });
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this. A little more verbose but feels more natural than choose

@tivac
Copy link
Contributor

tivac commented Nov 5, 2023

I love this, is there any conversation or references anywhere about where it came from?

@davidkpiano
Copy link
Member Author

I love this, is there any conversation or references anywhere about where it came from?

Some conversation here: https://discord.com/channels/795785288994652170/1169717611416789083

It builds up from previous discussions about a capture() API, but most recently, just the frustration in typing choose() and pure() 😅

@asfktz
Copy link

asfktz commented Nov 6, 2023

How will it behave with async logic?

I imagine new users will attempt something like this:

actions: createAction(async ({ context, event, exec }) => {
  exec.assign({ isFetching: true });
  
  const res = await fetchTodos(1000);
  
  exec.assign({ todos: res.data, isFetching: false });  
})

@Andarist
Copy link
Collaborator

Andarist commented Nov 6, 2023

Async logic would not be permitted here

@asfktz
Copy link

asfktz commented Nov 7, 2023

Async logic would not be permitted here

Sounds perfect to me 👌

Also, I'm curious, what is the reason behind using exec.assign / exec.action / etc..
over just exec(assign({}))?

Are they just shortcuts for better DX?

While I do like it, I wonder about the case of using a custom assign, like @xstate/immer.
If the rest of the machine is using @xstate/immer's assign, it may be confusing to have access to the default assign on exec.assign.

Without the shortcuts, it's one less thing to think about.

import { assign } from '@xstate/immer';

//...

actions: [
  // a custom assign imported from "@xstate/immer"
  assign(({ context }) => {
    context.value = 'foo';
  }),
  createAction(({ context, event, exec }) => {
    // The assign we're using for the rest of the machine
    exec(assign({
      count: context.count + 1
    }));
  })
]

What do you think?

@davidkpiano
Copy link
Member Author

Also, I'm curious, what is the reason behind using exec.assign / exec.action / etc..
over just exec(assign({}))?

Makes typing stronger; no need to infer types, which isn't perfect. We can strongly type exec.assign etc. upfront.

@Andarist Andarist changed the title [v5] createAction() (replaces pure() and choose()) [v5] enqueueActions() (replaces pure() and choose()) Nov 28, 2023
@Andarist
Copy link
Collaborator

Without the shortcuts, it's one less thing to think about.

Note that this should still "just work" - so you can very much do this.

@Andarist Andarist merged commit 7bcc62c into next Nov 30, 2023
@Andarist Andarist deleted the v5/createAction branch November 30, 2023 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants