The complexity of frontend applications over the years led to the creation of more robust solutions, where data logic won’t be messed up at scale. A shift took place from the traditional services approach, in which data is tightly coupled to the Views of their Components, towards more composable and shareable solutions. Each of these solutions is what we call a "state-manager".
Goal of this presentation is the comparative analysis between different react frontend state managers such as Redux, MobX, Recoil and React-Query. State Machines will also be presented, showing a completely different perception of how state can be orchestrated. Different mental models of the aforementioned state managers along with their different technical implementations will be presented to the audience. Ultimately, the audience can use this presentation for future reference on faster deciding which state-manager fits their own projects. Before delving into the comparison there will be a description of the main data flow in the browser. Concepts like reactivity, immutability, predictability, concurrency and performance will be detected on the main flow and will act as our comparison metrics among the state-managers.
Battle of React State Managers in frontend applications
1. The battle of react global state
managers in web applications
Evangelia Mitsopoulou
Founder | Senior Frontend Engineer | Semantic Web Analyst | Writer
evangelia.me
https://www.linkedin.com/in/evangelia-mitsopoulou-
5765135/
20.02.24 - GreeceJS, Impact Hub Athens
2. Data Fetching Flow during first Page Load
Proxy Server Database
Browser
cache
1. Data transformation
2. Data binding
3. Data rendering
4. Data visualization
Data fetching
js- logic
Data fetching
3. Data Fetching Flow during first Page Load
Loading State
Error State
Concurrency
Rendered Data
5. Problems to solved by global state
■ Issues with Predictable State Changes
■ Performance issues
■ Lack of Consistency
■ Concurrency issues
■ Caching issues
■ Scalability Testing and time travel debugging
6. When do we need a global state?
■ Complex applications with dependencies of data
■ Server side data fetching as database cache
■ Repeated calculations
■ Deep nested component hierarchies
■ Share User-input data
■ Broadcast messaging on event driven communication
■ Centralized handling of loading indicator
7. State management is …
■ How we handle the transition from one state to the other
State
Manager
8. Conceptual Framework
Atomic
03 ● Breaks down state into smaller,
independent pieces
Unidirectional
01
● Data flow towards one
direction, from store to the
components
Reactive
02
● Focus on automatic updates at
the components based on
changes on the state
State Machines
04
● Collection of finite states,
events and transitions between
states. Local state friendly
9. Conceptual Framework
Cache Friendly
05
● Works well with data fetching,
caching, retries, deduping and
synching,
React Built-in
06
● Data needs to be accessible by
many components at different
nested levels
10. React State Managers
Ecosystem Redux
Zustand
Vuex/Pinia
Ngrx/Store
MobX
Valtio
Akita
XState
Hooks + Context
Hooks + Props
Drilling
Reactive
Recoil
Jotai
Atomic Finite State Machines
Unidirectional
React Built-in
React Query
Data fetching friendly
SWR
11. Unidirectional Redux Toolkit
Increment
Component A
dispatch action
CounterSlice
Reducer
State
rerender/reacts
update/mutate
copy
Component B
Counter
rerender/reacts
{ .. }
(js-object)
Remember?
Counter: 1
{
type: 'INCREMENT'
payload '1'
}
(useSelector)
(dispatch(increment()
))
(useSelector)
Store
17. Bidirectional/Reactive: MobX
Increment
Component A
Component B
Counter
observer
● *Implemented as class
● All properties are marked as
observable so that they are
tracked
Remember?
observer
react:rerender
action/update value
CounterStore
State
observable values*
f1
actions
f2
Counter: 1
28. React Query
■ It is an async state manager
■ Comes with smart fetching, caching, synchronising, and updating the server
state (persistent state) in your react application
Client State
URL / Router
Server State
Client
LocalStorage, Session
Storage, Cache API,
Cookies, IndexedDB
Persistent State
29. Why React Query?
■ Simplifies data fetching - Erases a lot of boilerplate and makes
your code easy to read.
■ Improves the reliability of server data by invalidates them
■ Provides tools to improve User Experience - Prefetching, re-
fetching, caching, and more.
■ Performance optimisations - Pagination and lazy loading.
■ Request Retries - Ability to retry in case of errors.
■ Window Focus Refetching - Refetching based on application tab
activity
30. TanStack Query
■ Formerly known as React Query v3
■ Aims to make the React Query async state manager, available
to frameworks beyond React, and comes with a variety of new
features
■ It exists now for
○ React @tanstack/react-query (React Query v4)
○ Svelte @tanstack/svelte-query
○ Solid @tanstack/solid-query
○ Vue @tanstack/vue-query
39. State machines: Definition
■ Maths: A finite state machine is a mathematical model of
computation that describes the behavior of a system that
can be in only one state at any given time
■ Frontend: State machines are a formal and declarative way
to model and manage the state of an application. They
define all possible finite states that an application can go
through. Through events we can transite from one state to
the other
40. State machines UI Development
Finite State: is like a Behavior
which depending on the state
behaves different on events i.e.
click Play Button
State Video Playing
State Video Paused
click(PlayButton)
click(Pause Button)
Behavior C
State Machine
State Video not started
Behavior A
Behavior B
41. Traditional Event-driven UI Development
Init State
■ There is almost infinite set
of things that can be done
to a UI
■ Each element has a wide
range of possible mutations
Same state, different values on its
UI properties, after triggering events
42. State Machines - Core Concepts
■ Statecharts: Built on top of state machines for more
complicated mechanics
■ Actor Model: An actor is an own entity which can have its one
state machines or statecharts
43. ■ Not tight to a framework or language
■ Local State first. Use Context for global state
■ XState is a JavaScript/TypeScript implementation of finite
state machines and statecharts. It is like useReducer, for local
Components state. Could be used globally as well in
collaboration with context or useQuery
State Machines - Core Concepts
53. Metrics Comparison Table
Feature Redux MobX Recoil Ngrx/Store Vuex XState
Immutability Enforces
immutability
through
reducers
Mutable
observables
Mutable atom
values
Enforces
immutability
through
reducers
Enforces
immutabilit
y through
mutations
Emphasizes
immutability
through state
machines
Predictability Actions,
Reducers,
Centralized
Store
Reactive
programming,
Observables
Atom-based
state
management
Actions,
Reducers,
Centralized
Store
Actions,
Mutations,
Centralize
d Store
Finite State
Machines,
State Charts
54. Metrics Comparison Table
Feature Redux MobX Recoil Ngrx/Store Vuex XState
Concurrency Limited due to
single state
tree
Good support
for
concurrency
with reactions
Limited
support for
concurrent
reactions
Supports
concurrency
through
actions
Supports
concurrency
through
mutations
Built with
concurrency
in mind
Performance Efficient update
through
Redux's diffing
Efficient due
to reactive
updates
Efficient,
but
depends
how atoms
are used
Efficient with
selective
memoization
Efficient
with Vue's
reactivity
system
Emphasizes
efficiency in
state
transitions
55. State Manager Destructuring
Fetching - Caching
Server state
TanStack Query
All possible states
Fetching
fetch/axios/http
Framework agnostic pieces
State Machines
Handling Async
Rxjs,
Middlewares,
Promises
Client state
Composable atomic
units
Server-side
rendering
56. Future trends for state management
■ Move away from monolithic solutions like Redux to more
atomic ones like Recoil, Zustand
■ Emphasis on composability and reusability
■ Emphasis on developer experience
■ Cache friendly
■ Server side state management
58. Data Transformation
■ Change name convention: i.s snake_case them
■ Add new fields for data normalization: key / id
■ Make data type-safe and on the desired shape for runtime
because Typescript solves problems during compilation time.
61. Data rendering
■ The process of generating visual representation based on input
data or instructions
■ Templating (Render Tree Construction)
○ HTML Parsing - Bytes -Tokenization - Nodes
■ DOM Construction
■ CSSOM Construction
■ Layouting
○ Mathematical calculation of the size and position of the
nodes
■ Painting
○ Actual positioning of the calculated elements on the screen
62. Concurrency
■ Definition: The ability of a web application to manage and execute
multiple tasks simultaneously
○ Rendering user interface
○ Making asynchronous requests
○ Processing user interactions in a non-blocking way
○ Service Workers
○ Error handling
63. Concurrency
■ Key aspects
○ Asynchronous programming
○ Multithreading - Web Workers
○ Event Loop
○ Concurrency control (throttling, debouncing)
○ Service Workers
○ Error handling
64. State: Definition
■ The state is just a snapshot or representation of the
system from the client-side at a given point in time
■ It includes things such as:
○ User preferences
○ User input
○ Navigation information
○ Fetched Data from API
Editor's Notes
We used to have the battle of the frameworks, and on top of that we have a new competition which is the battle of state managers. There are state management libraries specific to a framework, while others have implementations in different frameworks.
So we have framework-specific and cross-framework state managers.Why all this noise? So much fuss about it? Because they all try to solve problems around a core ingredient of a web application, which is the data. We have clientside-rendered and data-heavy web applications. So it's important to understand how data flow.
On this slide, we have a visual representation of the data flow during data-fetching phase. This is the phase that often refers to the case - As soon as we enter a url- Databases are serving the data
- Sometimes we hit proxy servers, for caching for better future retrieval
- And before data are display/rendered as pixels in the screen there are some standard sub-processes that always take place
a) data transformation b) data-binding c) data-rendering d) data visualisation
Most core web frameworks do not come with an opinionated way of fetching or updating data in a holistic way.
Chatgbt
Race Condition: If multiple users can update their shopping carts simultaneously, without proper synchronization, it can result in race conditions. For instance, if two users add the same item to their cart simultaneously, the application might struggle to determine the correct quantity or total price.
To describe on the 2nd screen that with websockets it will be automatically updated, otherwise the browser needs refresh
Problems detected above:- Responsiveness: when we remove the item the UI need immediately to be updated and response to user interaction
- Need for consistency and a central store and predictability cause on 2nd screen there is info dependant
- Optimization: we can avoid unnecessary http requests if we store data in memory and be accessible in other screens. We can avoid unnecessary re-renders if we carefully manage the state. Redux does it automatically and other libs. Context not, as it dosn't have any state.
- Need for predicitasbility
- Synchronisatin- Caching: Whatchout: if data need to be updated we will need http request, or polling, or websockets. And then state is updated with most recent data and this update is also reflected in the other parts of the application.useQuery would be a great solution to such problems, as it handles itself all of this syncing logic. It checks if data are stale and if a new request is needed.
- Highlight and visualize in the previous design the problems that occur when we handle with data
1. There is need for consistency, otherwise we repeat the avatar name, so duplication of code, extra http request, worst performance
2. As soon as we remove the item, the page needs to be re-rendered and responsive. This can be slow, depending on how we handle updates+reactivity. Additionally this change should be reflected on the other pages where the same component is updated. We can avoid extra http request and use client-side state, if the nature of the data are not often changeable.
Predictability:
By following specific patterns or techniques, state management ensures that state changes are predictable and can be easily traced or debugged.
Reactivity:
State management enables the application to react to changes in data and update the user interface accordingly.
Consistency:
State management ensures that the application’s data remains consistent and up-to-date across different components and modules.
Scalability:
Proper state management is crucial as it will facilitate the handling of complex data and interactions as the application gets scaled in the future.
Lack of Consistency via a Shared centralized state ((all components have access to a single place and we try to avoid inconsistency)
Predictable State Changes (the change you make is expected to be made as such and reflected accordingly to other parts of the application)
Performance optimization ((by optimizing state updates and re-rendering).
Scalability Testing and debugging
Synchronization (handling asynchronous states) Handle both user interactions and asynchronous requests. So orchestrate them better.
State management libraries in software development solve several problems related to managing the state of an application. Here are some of the key issues that these libraries address:
1. **Complex State Handling**: Applications often have complex and nested states, such as user interface components, user data, and application settings. State management libraries provide a structured way to define, update, and access this state.
2. **Shared State**: In large applications, multiple components or modules may need access to the same data. State management libraries offer a centralized way to store and share this data, making it easier to keep it consistent and up to date.
3. **Predictable State Changes**: Managing state changes manually can lead to unpredictable behavior and bugs. State management libraries enforce a set of rules and patterns, such as immutability, to ensure that state transitions are predictable and traceable.
4. **Performance Optimization**: Inefficient state management can lead to unnecessary re-renders or updates in a user interface. State management libraries often include optimizations like memoization or diffing algorithms to minimize these performance issues.
5. **Data Flow Control**: Ensuring that data flows in a predictable and unidirectional manner is crucial for maintaining a maintainable and debuggable codebase. State management libraries often encourage a unidirectional data flow, making it easier to understand and debug data changes.
6. **Synchronization**: In applications with asynchronous data updates (e.g., network requests), it's crucial to synchronize state changes and UI updates. State management libraries often provide mechanisms for handling asynchronous operations and updating the state accordingly.
7. **Testing and Debugging**: State management libraries can simplify the process of testing and debugging an application. They often come with tools and patterns for inspecting, mocking, or replaying state changes, making it easier to diagnose and fix issues.
8. **Scalability**: As applications grow in complexity, managing state becomes increasingly challenging. State management libraries offer scalable solutions for handling state in a maintainable way, reducing the risk of introducing bugs as the codebase grows.
9. **Code Organization**: State management libraries often provide a clear structure for organizing state-related code, which can make the codebase more organized and easier to work with, especially in large teams.
10. **Code Reusability**: Many state management libraries allow you to create reusable state containers and reducers, making it easier to share state management logic across different parts of the application.
In summary, state management libraries solve problems related to organizing, centralizing, and efficiently handling the state of an application, which can lead to more predictable behavior, better performance, and easier maintenance in complex software projects.
bard
State management libraries solve a number of problems that developers face when building complex applications, including:
Centralized state management: State management libraries provide a central place to store and manage the application state. This makes it easier to keep track of state changes, ensure that all components have access to the latest state, and avoid inconsistencies.
Predictable state updates: State management libraries provide a predictable way to update the application state. This helps to prevent errors and unexpected behavior.
Performance: State management libraries can improve the performance of applications by optimizing state updates and re-rendering.
Scalability: State management libraries can help applications to scale by making it easier to add new features and components without introducing state management problems.
Some specific problems that state management libraries solve include:
Managing state across multiple components: State management libraries make it easy to share state between different components in an application. This is especially important in large applications with many complex components.
Handling asynchronous state updates: State management libraries provide a way to handle asynchronous state updates in a predictable and consistent way. This is essential for applications that need to respond to user interactions and changes in external data sources.
Debugging: State management libraries can make it easier to debug applications by providing tools for tracking state changes and identifying the source of problems.
Overall, state management libraries can help developers to build more reliable, performant, and scalable applications.
Here are some additional benefits of using state management libraries:
Improved code readability and maintainability: State management libraries can help to make code more readable and maintainable by separating the state management logic from the component logic.
Reduced boilerplate code: State management libraries can help to reduce the amount of boilerplate code that developers need to write, freeing up their time to focus on more important tasks.
Increased developer productivity: State management libraries can help to increase developer productivity by providing a set of tools and patterns for managing state effectively.
Codeproject]
Lack of Consistency via a Shared centralized state ((all components have access to a single place and we try to avoid inconsistency)
Predictable State Changes (the change you make is expected to be made as such and reflected accordingly to other parts of the application)
Performance optimization ((by optimizing state updates and re-rendering).
Scalability Testing and debugging
Synchronization (handling asynchronous states) Handle both user interactions and asynchronous requests. So orchestrate them better.
State management libraries in software development solve several problems related to managing the state of an application. Here are some of the key issues that these libraries address:
1. **Complex State Handling**: Applications often have complex and nested states, such as user interface components, user data, and application settings. State management libraries provide a structured way to define, update, and access this state.
2. **Shared State**: In large applications, multiple components or modules may need access to the same data. State management libraries offer a centralized way to store and share this data, making it easier to keep it consistent and up to date.
3. **Predictable State Changes**: Managing state changes manually can lead to unpredictable behavior and bugs. State management libraries enforce a set of rules and patterns, such as immutability, to ensure that state transitions are predictable and traceable.
4. **Performance Optimization**: Inefficient state management can lead to unnecessary re-renders or updates in a user interface. State management libraries often include optimizations like memoization or diffing algorithms to minimize these performance issues.
5. **Data Flow Control**: Ensuring that data flows in a predictable and unidirectional manner is crucial for maintaining a maintainable and debuggable codebase. State management libraries often encourage a unidirectional data flow, making it easier to understand and debug data changes.
6. **Synchronization**: In applications with asynchronous data updates (e.g., network requests), it's crucial to synchronize state changes and UI updates. State management libraries often provide mechanisms for handling asynchronous operations and updating the state accordingly.
7. **Testing and Debugging**: State management libraries can simplify the process of testing and debugging an application. They often come with tools and patterns for inspecting, mocking, or replaying state changes, making it easier to diagnose and fix issues.
8. **Scalability**: As applications grow in complexity, managing state becomes increasingly challenging. State management libraries offer scalable solutions for handling state in a maintainable way, reducing the risk of introducing bugs as the codebase grows.
9. **Code Organization**: State management libraries often provide a clear structure for organizing state-related code, which can make the codebase more organized and easier to work with, especially in large teams.
10. **Code Reusability**: Many state management libraries allow you to create reusable state containers and reducers, making it easier to share state management logic across different parts of the application.
In summary, state management libraries solve problems related to organizing, centralizing, and efficiently handling the state of an application, which can lead to more predictable behavior, better performance, and easier maintenance in complex software projects.
bard
State management libraries solve a number of problems that developers face when building complex applications, including:
Centralized state management: State management libraries provide a central place to store and manage the application state. This makes it easier to keep track of state changes, ensure that all components have access to the latest state, and avoid inconsistencies.
Predictable state updates: State management libraries provide a predictable way to update the application state. This helps to prevent errors and unexpected behavior.
Performance: State management libraries can improve the performance of applications by optimizing state updates and re-rendering.
Scalability: State management libraries can help applications to scale by making it easier to add new features and components without introducing state management problems.
Some specific problems that state management libraries solve include:
Managing state across multiple components: State management libraries make it easy to share state between different components in an application. This is especially important in large applications with many complex components.
Handling asynchronous state updates: State management libraries provide a way to handle asynchronous state updates in a predictable and consistent way. This is essential for applications that need to respond to user interactions and changes in external data sources.
Debugging: State management libraries can make it easier to debug applications by providing tools for tracking state changes and identifying the source of problems.
Overall, state management libraries can help developers to build more reliable, performant, and scalable applications.
Here are some additional benefits of using state management libraries:
Improved code readability and maintainability: State management libraries can help to make code more readable and maintainable by separating the state management logic from the component logic.
Reduced boilerplate code: State management libraries can help to reduce the amount of boilerplate code that developers need to write, freeing up their time to focus on more important tasks.
Increased developer productivity: State management libraries can help to increase developer productivity by providing a set of tools and patterns for managing state effectively.
A state management library will be helpful to get the following things done:
Model your application state
Derive computed values from it
Monitor it for changes
It encapsulates different types of state:
- Ui state: for controlling interactive parts of our application like modals, or theme
- Server-caching state
we call some api, cache response and use it (i.e. swr)
in the early days of just fetching api, using result.
Components dispatch actions to store
Reducers act upon actions and mutate store
Store sends update down to components
https://mobx.js.org/README.html
Observables are just functions that throw values, and objects know as observers subscribe to these values
There is no need to manually optimize components with error-prone and sub-optimal techniques like memoization and selectors.
All you do is a bunch of values and you just grab them as observables values. that means when it updates, everything that depends on it is updated. if we mutate this value, no need to dispatch and action. This mutation cause mutations everywhere. It's more smart comparable to how you would do it yourself.
mobx is still predictable, but it's not super predictable as redux
You store info in an atom. You set value, You can get value from atoms.
You can connect atoms.
Atomic State Management involves utilizing Atoms as a central repository for state management.
It can be seen as an upgraded version of the useState hook, allowing for state sharing between components. This approach combines the benefits of both component state and global store patterns
Atoms are used as single source of state, Nice loose coupling.
Why to use that? If you like loose coupling but don't want to use RXJS
Jotai is event better, can be connected with XState
https://www.wednesday.is/writing-articles/react-query-the-what-how-when
React Query complements these libraries and helps create a separation of concerns. In most client-side applications, they deal with the server state.
https://tanstack.com/query/v4/docs/react/guides/query-invalidation
Waiting for queries to become stale before they are fetched again doesn't always work, especially when you know for a fact that a query's data is out of date because of something the user has done. For that purpose, the QueryClient has an invalidateQueries method that lets you intelligently mark queries as stale and potentially refetch them too
Is it the newest kid on the block? It's a hyped library?
https://podcasts.apple.com/lu/podcast/from-redux-to-xstate-with-david-khourshid/id1546641347?i=1000520331521
It's a great implementation of state machines and statecharts and actors.
In other libraries we mostly think about WHERE we store data. We discuss how these data changes over time and how it can't change. We separate that by state machines.
finit state is like a behavior which depending on the state behaves different on events.
it's all about separating behaviors of your application state and transitioning between themState machines is a collection of states, events and transitions between states.
Statecharts are built on top of statemachines for more nested/parallel and a lot of other mechanisms that let state machines scale.The actor model builds on top of them, where an actor is an entity where inside has its own state machine or statechart. An actor can talk to other actors.
The question of should I use it or not is not correct. Is about should I make it implicit or explicit?
Benefits: Beeing able to know everything that happened and that can happen. In Redux time-travelling debugging,here we go one step further, Cause we can draw what can happen, all possible scenarios.
It's also a visual language in a graph (lines between events and states): that can help product managers, designers and different developers
Benefits: You have to handle all the states, You need to be explicitly, you need to know all the states, while in other cases you handle the states you are aware of. An example where this could work is react query with strict typing. This is like a simpler version of how state machine works.
We overestimate ourselves that we know what can happen.We see buggy applications:- where the loading spinner keeps showing: why? internet connection time out?
How Xstate relates to Redux? Which parts of Redux can be replaced by XState?
Redux: Is single global atomic. It's global first. You cannot use it locally.
Xstate is local-first, which means to replace useReducer and useSate at the component Level.
The mechanics are very similar:- Redux is about dispatching actions, XState about sending events
useEffects in Redux are afterthoughts, you need to handle them with middleware
side effects in xState are pickedIn the machine Model, so their outputs can be thought of as side effects/actions.
You don't need necessarily XState to implement state machines, you can also use Redux. But needs a lot of discipline.
State machines have nothing to do with any framework and language at all.XState has a few hooks:- useMachine, which essentially a replacement of useReducer. It can spawn actors, it can have sideEffects
- regarding usingContext, you can use useInterpret, lets you put in the machine in there, gets instance of the machine (like a subscribe object) and once you pass that to context you can useService to pass to any component
actors to communicate with different state machines, and we delegate some tasks that are outside state machine.
FiniteMachines
https://kyleshevlin.com/guidelines-for-state-machines-and-xstate
A state machine, more specifically a finite state machine, is a means of representing all the possible enumerated states of a system and the possible enumerated transitions between states in that system.
https://statecharts.dev/use-case-statecharts-in-user-interfaces.html (traditiona event driven interfaces)
In a traditional event driven user interface component, say, the ubiquitous HTML <input> element, the UI component generates a lot of events, that the developer can subscribe to, from gaining or losing focus, editing, selecting, mouse movement and so on. A developer has a plethora of events to choose between. There is a similar almost infinite set of things that can be done to a user interface. Each element has a wide range of possible mutations. It is up to the developer to decide what to do based on whatever event that happens.
In other libraries we mostly think about WHERE we store data. We discuss how these data changes over time and how it can't change.
By state machines we separate that.
finit state is like a behavior which depending on the state behaves different on events.
it's all about separating behaviors of your application state and transitioning between themState machines is a collection of states, events and transitions between states.
Statecharts are built on top of statemachines for more nested/parallel and a lot of other mechanisms that let state machines scale.The actor model builds on top of them, where an actor is an entity where inside has its own state machine or statechart. An actor can talk to other actors.
The question of should I use it or not is not correct. Is about should I make it implicit or explicit?
Benefits: Beeing able to know everything that happened and that can happen. In Redux time-travelling debugging,here we go one step further, Cause we can draw what can happen, all possible scenarios.
It's also a visual language in a graph (lines between events and states): that can help product managers, designers and different developers
Benefits: You have to handle all the states, You need to be explicitly, you need to know all the states, while in other cases you handle the states you are aware of. An example where this could work is react query with strict typing. This is like a simpler version of how state machine works.
We overestimate ourselves that we know what can happen. We see buggy applications:- where the loading spinner keeps showing: why? internet connection time out?
How Xstate relates to Redux? Which parts of Redux can be replaced by XState?
Redux: Is single global atomic. It's global first. You cannot use it locally.
Xstate is local-first, which means to replace useReducer and useSate at the component Level.
The mechanics are very similar:- Redux is about dispatching actions, XState about sending events
https://statecharts.dev/use-case-statecharts-in-user-interfaces.html (traditiona event driven interfaces)
In a traditional event driven user interface component, say, the ubiquitous HTML <input> element, the UI component generates a lot of events, that the developer can subscribe to, from gaining or losing focus, editing, selecting, mouse movement and so on. A developer has a plethora of events to choose between. There is a similar almost infinite set of things that can be done to a user interface. Each element has a wide range of possible mutations. It is up to the developer to decide what to do based on whatever event that happens.
In other libraries we mostly think about WHERE we store data. We discuss how these data changes over time and how it can't change.
By state machines we separate that.
finit state is like a behavior which depending on the state behaves different on events.
it's all about separating behaviors of your application state and transitioning between themState machines is a collection of states, events and transitions between states.
Statecharts are built on top of statemachines for more nested/parallel and a lot of other mechanisms that let state machines scale.The actor model builds on top of them, where an actor is an entity where inside has its own state machine or statechart. An actor can talk to other actors.
The question of should I use it or not is not correct. Is about should I make it implicit or explicit?
Benefits: Beeing able to know everything that happened and that can happen. In Redux time-travelling debugging,here we go one step further, Cause we can draw what can happen, all possible scenarios.
It's also a visual language in a graph (lines between events and states): that can help product managers, designers and different developers
Benefits: You have to handle all the states, You need to be explicitly, you need to know all the states, while in other cases you handle the states you are aware of. An example where this could work is react query with strict typing. This is like a simpler version of how state machine works.
We overestimate ourselves that we know what can happen. We see buggy applications:- where the loading spinner keeps showing: why? internet connection time out?
How Xstate relates to Redux? Which parts of Redux can be replaced by XState?
Redux: Is single global atomic. It's global first. You cannot use it locally.
Xstate is local-first, which means to replace useReducer and useSate at the component Level.
The mechanics are very similar:- Redux is about dispatching actions, XState about sending events
https://codesandbox.io/s/react-query-observables-2h9tw?file=/src/App.tsx:212-235
react query with observables
DEFINITION
Data binding is a connector between user interface and business logic, between destination and source.
How data are binded in the UI
When a javascript variable displays some value in the HTML
DEFINITION
How data are binded in the UI
When a javascript variable displays some value in the HTML