Effects
Developing applications is not only about managing state, but also managing side effects. A typical side effect would be an HTTP request or talking to localStorage. In Overmind we just call these effects. There are several reasons why you would want to use effects:
All the code in your actions will be domain specific, no low level generic APIs
Your actions will have less code and you avoid leaking out things like URLs, types etc.
You decouple the underlying tool from its usage, meaning that you can replace it at any time without changing your application logic
You can more easily expand the functionality of an effect. For example you want to introduce caching or a base URL to an HTTP effect
The devtool tracks its execution
If you write Overmind tests, you can easily mock them
You can lazy-load the effect, reducing the initial payload of the app
Exposing an existing tool
Let us just expose the AXIOS library as an http effect.
We are just exporting the existing library from our effects file and including it in the application config. Now Overmind is aware of an http effect. It can track it for debugging and all actions and operators will have it injected.
Let us put it to use in an action that grabs the current user of the application.
That was basically it. As you can see we are exposing some low level details like the http method used and the URL. Let us follow the encouraged way of doing things and create our own api effect.
Specific API
It is highly encouraged that you avoid exposing tools with their generic APIs. Rather build your own APIs that are more closely related to the domain of your application. Maybe you have an endpoint for fetching the current user. Create that as an API for your app.
Now you can see how clean your application logic becomes:
Initializing effects
It can be a good idea to not allow your side effects to initialize when they are defined. This makes sure that they do not leak into tests or server side rendering. For example if you want to use Firebase, instead of initializing the Firebase application immediately we rather do it behind an initialize method:
We are doing two things here:
We use an IIFE to create a scoped internal variable to be used for that specific effect
We have created an initialize method which we can call from the Overmind onInitialize action, which runs when the Overmind instance is created
Example of initializing the effect:
Effects and state
Typically you explicitly communicate with effects from actions, by calling methods. But sometimes you need effects to know about the state of the application, or maybe some internal state in the effect should be exposed on your application state. Again we can take advantage of an initialize method on the effect:
Here we are passing in actions that can be triggered by the effect to expose internal state and/or other information that you want to manage.
Lazy effects
You can also lazily load your effects in the initialize method. Let us say we wanted to load Firebase and its API on demand, or maybe just split out the code to make our app start faster.
In our initialize() we would just have to wait for the initialization to finish before using the API:
We could have been even bolder here making our effect download its dependency related to using any of its methods. Imagine for example the firebase library downloading when you run a login method on the effect.
Configurable effect
By defining a class we can improve testability, allow using environment variables and even change out the actual implementation.
We export an instance of our Api to the application. This allows us to also create instances in isolation for testing purposes, making sure our Api class works as we expect.
Summary
Importing side effects directly into your code should be considered bad practice. If you think about it from an application standpoint it is kinda weird that it runs HTTP verb methods with a URL string passed in. It is better to create an abstraction around it to make your code more consistent with the domain, and by doing so also improve maintainability.
Last updated