menu

Statecharts

Statecharts are a precise, visual way of modeling the behaviour of complex reactive systems. They describe how things work, and can help you get your code doing exactly what you want.

Channels
Team
Posts
Chat
Members
Info
Show previous messages

March 5, 2020 at 2:10am
Cool, I guess that make sense. Is this the recommended way of defining actions, or can we use assign in another way that makes it easier for typescript?
  • reply
  • like

March 5, 2020 at 10:21am
or can we use assign in another way that makes it easier for typescript?
In V5 we will make assign a direct property of the transition:
on: {
SOME_EVENT: {
// just like normal assign
assign: { count: 0 },
assign: { count: (context) => context.count + 1 },
assign: (context) => ({ count: context.count + 1 }),
assign: [
{ count: 0 },
{ otherCount: (context) => context.count + 10 }
]
}
}
like-fill
2
  • reply
  • like
Doesn't that put functions in the configuration though that are recommended to be defined in the createMachine's second options.actions parameter?
  • reply
  • like
Good question. You can still use assign() action creators as normal
  • reply
  • like
Hey! I'm a xstate noob and trying to play around with a state machine for a pannable component. I'm trying to get it working with fairly strict typescript types and ran into some problems, with the events not being the correct types for my actions. I dug around for similar issues and found one, https://github.com/davidkpiano/xstate/issues/866. Unfortunately I couldn't get any of the suggestions to work. I assume it is an inference problem, I just don't know how to work around it.
If anyone with typescript experience has a minute I would love to get some directions. Codesandbox:
Hi Joachim,
Instead of relying on automatic type inference, you should just type them explicitly for now. Since you're creating a type per event, that's easy for you to do - if anyone else prefers to use discriminated unions, I've created this helper:
export type SpecificEvent<
X extends XEventObject,
T extends X["type"]
> = X extends Event<T, infer U> ? Event<T, U> : never
type Event =
{ type: "AUTH.LOGGED_IN"; token?: Token }
| { type: "AUTH.LOGGED_OUT" }
export type AuthEvent<T extends Event["type"]> =
SpecificEvent<Event, T>
assign((ctx, ev: AuthEvent<"AUTH.LOGGED_IN">) => ({token: ev.token}))
Edited
like-fill
2
  • reply
  • like

March 6, 2020 at 3:28am
Thanks everyone!
  • reply
  • like

March 7, 2020 at 5:32am
I think your solution makes sense but I'm still confused about some parts.. I assumed that XEventObject is from xstate import {EventObject from 'xstate'? Where does the event generic Event<T, infer U> come from? The event exported from xstate only take one type parameter. If you open the codesandbox you can see typescript complaining: Generic type 'Event' requires 1 type argument(s).ts(2314)
Edited
  • reply
  • like

March 8, 2020 at 10:55pm
You need to import { Event } from 'xstate' as well.
  • reply
  • like
I'm doing that in the codesandbox.
Edited
  • reply
  • like
Generic type 'Event' requires 1 type argument(s).ts(2314)
  • reply
  • like
you're absolutely right! I defined my own event type:
export type Event<T = string, D = {}> = { type: T } & D
Edited
  • reply
  • like
Nice! I probably should have figured that out. Thanks again 👌
  • reply
  • like
It works quite nice, but it means that we cant pass a schema and/or Events to the Machine generic. Since the action functions are typed with a different signature
ActionFunction<PanContext, Event<"PARENT_DATA", PARENT_DATA>>' is not assignable to type 'ActionFunction<PanContext, Events>
  • reply
  • like

March 21, 2020 at 11:43am
Alrighty, after reading Kent C Dodd's article on Xstate and state machines, and realising that my current project is in desperate need of one, I think I'm going to finally spend the time to really learn how to implement this.
  • reply
  • like
My use case is a quiz, basically. User clicks 'start' and they answer 10 (or however many) questions and after each question they get shown if it was correct or not. Then at the end they get to view their overall results and time etc. It's a total mess using a reducer (my current approach) and feels like a state machine would be better.
  • reply
  • like
I'm currently having to do state.isFetching = 1; state.currentQuestion = state.currentQuestion ? ... logic here and it's a mess lol
  • reply
  • like
Welcome to the madness :D
like-fill
1
  • reply
  • like
You can store currentQuestion in context
  • reply
  • like

March 22, 2020 at 8:17am
Yep, I'm storing all that type of data in context :)
  • reply
  • like

March 22, 2020 at 5:56pm
Are the contributing guidelines out of date David? https://github.com/davidkpiano/xstate/blob/master/CONTRIBUTING.md
  • reply
  • like
I'm having trouble getting everything installed properly. Should I be using lerna specific commands?
  • reply
  • like
Running yarn dev resolved the issues.
  • reply
  • like

March 23, 2020 at 1:59pm
Feel free to PR changes to that doc, I'll update them ASAP
  • reply
  • like

April 3, 2020 at 2:32pm

April 6, 2020 at 1:23am
Hey, I've just made a simple game to learn xstate, could you guys please leave me some comments whenever I'm doing it right or is there anything that I can do to make the machine work better? Thank you.
The source code is here xstate-flipping-cards-game and the demo is here
  • reply
  • like