XState is not a replacement to redux, I still like my redux. They both serve different needs. I see XState as a perfect place to put the logic of components. If I would have to create the same table component but without XState, I would've ended up with some messy code that would be hard to comprehend.
XState can be used with React to: Coordinate local state. Manage global state performantly. Consume data from other hooks.
If you write a state machine that only has a single state, but modifies its context, what you've created is a reducer. It's hard to state just how difficult it is to talk about state management; it all depends on the context of the conversation.
A state machine is a mathematical abstraction used to design algorithms. A state machine reads a set of inputs and changes to a different state based on those inputs. A state is a description of the status of a system waiting to execute a transition.
I created XState, but I'm not going to tell you whether to use one over the other; that depends on your team. Instead, I'll try to highlight some key differences.
Redux | XState |
---|---|
essentially a state container where events (called actions in Redux) are sent to a reducer which update state | also a state container, but separates finite state (e.g., "loading" , "success" ) from "infinite state", or context (e.g., items: [...] ) |
does not dictate how you define your reducers - they are plain functions that return the next state given the current state and event (action) | a "reducer with rules" - you define legal transitions between finite states due to events, and also which actions should be executed in a transition (or on entry/exit from a state) |
does not have a built-in way to handle side-effects; there are many community options, like redux-thunk, redux-saga, etc. | makes actions (side-effects) declarative and explicit - they are part of the State object that is returned on each transition (current state + event) |
currently has no way to visualize transitions between states, since it does not discern between finite and infinite state | has a visualizer: https://statecharts.github.io/xstate-viz which is feasible due to the declarative nature |
the implicit logic/behavior represented in reducers can't be serialized declaratively (e.g., in JSON) | machine definitions, which represent logic/behavior, can be serialized to JSON, and read from JSON; this makes behavior very portable and configurable by external tools |
not strictly a state machine | adheres strictly to the W3C SCXML specification: https://www.w3.org/TR/scxml/ |
relies on the developer to manually prevent impossible states | uses statecharts to naturally define boundaries for handling events, which prevents impossible states and can be statically analyzed |
encourages the use of a single, "global" atomic store | encourages the use of an Actor-model-like approach, where there can be many hierarchical statechart/"service" instances that communicate with each other |
I will add more key differences to the docs this week.
State machine does not tell (force) you to have Unidirectional data flow. It has nothing to do with data flow. It is more about constraining state changes and about state transitions. So, generally only some parts of the application would be designed with State machines, only and only if you need to constraint/forbid some state changes and you are interested in transitions.
Beware that with state machines, if for some reason (external API dependency etc...), there is chance that app might get locked in a state where it can't transition to another state because of constraints, you have to solve it.
But if you are only interested in last app state itself, instead of state transitions, and state constraints do not matter, then you better be not using state machine and directly be updating state itself (you can still wrap state in a Singleton class update through Action classes).
On the other hand, Redux is Unidirectional architecture framework. Unidirectional architectures enforce you to have single direction of data flow. In Redux, it starts with User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View
. Like State Machines, you can trigger side effects with Middlewares in Redux. You can constraint/forbid State transitions, if you want. Different from State Machine, Redux forces unidirectional data flow, pure! reducer functions, immutable state objects, single observable app state.
few of my points below.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With