The Mental Model
Last updated
Was this helpful?
Last updated
Was this helpful?
With the react-states architecture imagine the application being mounted into an environment. Typically this environment is the browser, but removing that fact from the actual implementation creates an important separation. This separation is achieved by creating an environment interface.
With an environment interface it is possible for the application to operate with the same implementation in many different environments. Actually, the application has absolutely no idea what environment it is running in. Instead of traditionally making our applications obey the interface of its environment, we create our own interface, perfectly designed for our application and then the environment has to obey that interface instead.
Environments are also unpredictable. We often think about interactions with an environment to be of a synchronous nature, where nothing else can happen when we interact with it. In reality anything and everything can happen in between our request to interact with an environment and its response. This is why asynchronous code is difficult to manage, our application is constantly being bombarded by events. The ultimate goal is to wield these unpredictable events and create a predictable user experience.
Within the application you have features which holds all the application state and logic. The only way the application state move forward is through state transitions. This happens when a valid dispatch is sent to the feature, either an action or an environment event. State transitions can cause effects to execute, called a transition effect, which typically interacts with the environment interface causing new events to trigger. That means there are two sources for dispatches in your application. An action dispatch, typically from a component, and events from the environment.
The important detail to understand here is that action and event dispatches are guarded and produces only explicit states. With a traditional approach the user and environment would command the reducer to change its state. With react-states the user and the environment only notifies the reducer and the reducer only moves forward given the dispatch being valid for the current state.
Traditionally the environment, including user interaction, is driving the state of the application forward. This happens as a result of some response or event from the environment that triggers a dispatch and the reducer treats it as an order to change the state. Since the unpredictable environment is what is ordering the state changes, the UI consuming the state also becomes unpredictable. That in combination with the UI implementation having to interpret all the variations the state model can be in.
With react-states the environment is no longer driving the state of the application forward. It is up to the reducer to actually act on dispatches. It depends on its existing state. The reducer might or might not produce a new state which can be consumed by the UI.
The UI only needs to look at the explicit state property of the state to understand what to display to the user and what values are available in that state. With the help of TypeScript the state becomes even more powerful from the point of UI consumption. It will actually help us ensure that we are indeed implementing the state correctly and that we are considering all states.
The result of this is a React provider component we call a Feature. You can think of it as translating the unpredictable, imperative and reactive world of the application environment, into a predictable and declarative representation perfectly suited for UI consumption.