[javascript] Redux - multiple stores, why not?


Answers

In some very large enterprise apps with hundreds or thousands of reducers, it's often useful to think of different areas of the app as entirely separate apps. In those cases (where it really is multiple apps that share a domain name), I use multiple stores.

For example, I tend to treat the following common functionality areas as separate apps:

  • Admin
  • Analytics / data vis dashboards
  • Billing management & purchase flows
  • Enterprise account team/permission management

If any of those things are small, just keep them as part of the main app. If they grow very large (as some enterprise account management & analytics tools do), split them out.

The best way to manage very large apps is to treat them like a composition of many smaller apps.

If your app is less than say ~50k LOC, you should probably ignore this advice and follow Dan's advice, instead.

If your app is more than 1 Million LOC, you should probably be splitting out mini-apps, even if you maintain them in a mono repo.

Question

As a note: I've read the docs for Redux (Baobab, too), and I've done a fair share of Googling & testing.

Why is it so strongly suggested that a Redux app have only one store?

I understand the pros/cons of a single-store setup vs a multiple store setup (There are many Q&A on SO on this subject).

IMO, this architectural decision belongs to the app developers based on their projects' needs. So why is it so strongly suggested for Redux, almost to the point of sounding mandatory (though nothing is stopping us from making multiple stores)?

EDIT: feedback after converting to single-store

After a few months working with redux on what many would consider a complex SPA, I can say that the single store structure has been a pure delight to work with.

A few points that might help others understand why single store vs many store is a moot question in many, many use-cases:

  • it's reliable: we use selectors to dig through the app state and obtain context-relevant information. We know that all the needed data is in a single store. It avoids all questioning as to where state issues could be.
  • it's fast: our store currently has close to 100 reducers, if not more. Even at that count, only a handful of reducers process data on any given dispatch, the others just return the previous state. The argument that a huge/complex store (nbr of reducers) is slow is pretty much moot. At least we've not seen any performance issues coming from there.
  • debugging friendly: while this is a most convincing argument to use redux as a whole, it also goes for single store vs multiple store. When building an app you're bound to have state errors in the process (programmer mistakes), it's normal. The PITA is when those errors take hours to debug. Thanks to the single store (and redux-logger) we've never spent more than a few minutes on any given state issue.

a few pointers

The true challenge in building your redux store is when deciding how to structure it. Firstly, because changing structure down the road is just a major pain. Secondly, because it largely determines how you'll be using, and querying your app data for any process. There are many suggestions on how to structure a store. In our case we found the following to be ideal:

{
  apis: {     // data from various services
    api1: {},
    api2: {},
    ...
  }, 
  components: {} // UI state data for each widget, component, you name it 
  session: {} // session-specific information
}

Hopefully this feedback will help others.

EDIT 2 - helpful store tools

For those of you who have been wondering how to "easily" manage a single store, which can quickly get complex. There are a tools that help isolate the structural dependencies/logic of your store.

There is Normalizr which normalizes your data based on a schema. It then provides an interface to work with your data and fetch other parts of your data by id, much like a Dictionary.

Not knowing Normalizr at the time, I built something along the same lines. relational-json takes a schema, and returns a Table-based interface (a little like a database). The advantage of relational-json is that your data structure dynamically references other parts of your data (essentially, you can traverse your data in any direction, just like normal JS objects). It's not as mature as Normalizr, but I've been using it successfully in production for a few months now.




Having one store in Redux is really what we need in many cases, I both used Redux and Flux and believe Redux does the job better!

Don't forget the store is in a JavaScript Object, so while you have only one store, it can be easily extended and reused, to me, having one store make it much easier to traversing using Redux dev tools and not be mixed up in big applications...

Also the concept of one store is mimicking the database for us, one source of truth which you can change it and you can access it in the browser memory...

If the whole application be well-managed, one store can be enough to manage the whole application status...




Links