Electrode.io Adventures Part 1: Route based store initialization
The past few days I’ve been experimenting with @WalmartLabs’ Electrode. It seems like a rather interesting platform and it got my attention immediately as I stumbled upon it. I’m planning to write an article about it and what it offers to the programmer that employs it in his web app.
For now, I’ll just describe an issue I had when using it, and the solution I ended up with in order to fix it. Truth is, I really like the solution! I want to share it with you and also get your feedback on it!
According to electrode maintainers’ official response, there is no well defined way to initialize the store according to route. One way to accomplish it, as proposed by other members of the community, too, would be this:
match param gives us access to the used route, and thus we can generate our initial state conditionally based on the route.
What would be a clean way though to perform those checks?
Searching through the internet, I found many people advocating that we may use
componentDidMount on the top-level component that is rendered by the route in order to fetch/create that data.
Although this solution is indeed nice and clean, it didn’t really satisfy me. I had the notion that the store initialization was not the responsibility of a component, no matter its level in the hierarchy. But instead, it is something that should be taken care of by the route itself!
Thus I came up with the following solution:
To give each route in
routes.jsx an extra prop,
initialState , which describes the initial state to be loaded in the store. For ease of use and flexibility, this prop can either be an
object or an
action. Thus, reusability of actions is promoted!
This way, everything is arranged in a clean and readable manner, but most of all in a reusable architecture through the very actions that may be dispatched from elsewhere as well!
A while after I prototyped and posted my solution at the relevant thread, the electrode.io team released an improvement that enables you to define store initializers based on the routes, as well.
The official documentation can be found here.
This improvement enables you to specify an
init prop in each route whose value should be of either a
string value or
true . If it is
true, electrode.io will look for the store intializer in
src/server/routes/<route path prop>. If it is a
string, the store initializer needs to be located at
src/server/routes/<init prop value>. This store initializer needs to export a
configureStore function like the following:
So, you can have the following
And this corresponds to the following:
- Store for route
/is created with the default store initializer by
- Store for route
/some-routeis created by the initializer found at
- Store for route
/some-other-routeis created by the initializer found at
The main difference between this solution and the one I proposed, is that this one offers different store creators per route, whereas mine offers different initial states per route. Thus, if you need different middleware or reducers per route, this one may be the right one (although I don’t think multiple/variable top level reducers is the “Redux” way to go — I’m sure that the guys behind the platform had some other benefit in mind when designing the
init prop API).
However, if all your routes revolve around the same single page application, what you need is to just pre-fill the store with different data depending on the route. And, in my opinion, this is where my solution is better.
Regardless of the difference though, I was happy to see that the electrode.io team adapted a solution which matched my approach on tackling the issue, extending the routes themselves and not delegating the issue to the components!
I am awaiting for your comments and suggestions, I’d like to hear what you think! I’m sure your feedback can help make this solution even better!
PS: I’d be glad to hear @WalmartLabs team’s view on this, too!
PS2: Tune in for my next article in a week’s time, scoped around electrode.io again! I’ll describe how I tackled store initialization when data prefetching is needed. Of course without issuing internal HTTP requests against our own server!