question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Approach for using nested stores in a decoupled application

See original GitHub issue

Hey guys,

I have a complex use-case in mind and I’d like to pick your brain for correctly approaching this. Before explaining the problem, I know there have been related questions and I know there is no plan on supporting this, but hear me out.

Overview

Imagine I have an application with some main routes

<Route path="/" component={Application}>
  <Route path="dashboard" component={Dashboard} />
  <Route path="posts" component={PostsList} />
  <Route path="account" component={Account} />
</Route>

We can consider the Application container as simply the scaffolding component, which might include a TopNavigation and a LeftNavigation, and renders the child route as the main view. So each main route is basically rendered as the main view. That’s pretty standard.

The Application also has a “global” state, which might include user information, token for authentication and other stuff necessary for the overall functionality of the app. Of course this includes the related reducers, actions and so on. The root component of the app also is wrapped around a Provider, like it’s supposed to be.

The idea

Now image that all those main route components (Dashboard, PostsList, …) are considered as modules (or plugins, or extensions, whatever name you like) and are basically separated from the main application. Imagine a concept similar to babel or eslint, where you have the core and plugins that can be developed outside.

The idea is that I can develop my Dashboard module indipendently from the main application. For simplicity let’s say that each module simply exports its routes.

// dashboard
const DashboardRoot = props => (<h1>{'Dashboard'}</h1>)
const DashboardRoute = () => (
  <Route path="dashboard" component={DashboardRoot} />
)
export default DashboardRoute

The problem

Here some facts:

  • each module can have its own local store with reducers, actions and so on
  • modules are decoupled from each other
  • the main application doesn’t know about what’s going on in each module
  • modules can use and access the “global” state of the application (e.g. user)

Given that, I think it’s fair to assume that I would use, in each module, an own Provider.

const DashboardRoot = props => (
  <Provider store={store}>
    <h1>{'Dashboard'}</h1>
  </Provider>
)
const DashboardRoute = () => (
  <Route path="dashboard" component={DashboardRoot} />
)
export default DashboardRoute

At this point there is a problem though. A store already exists in the context as it was defined by the root Provider of the main app.

As suggested in previous questions regarding this topic (nested providers), passing manually the store as a prop is not an option, as e.g. I want to use all the goodnesses of connect.

A possible solution

Ideally speaking, I think we could replace the Provider in each module with some sort of local provider for each module. Let’s call this LocalProvider.

const DashboardRoot = props => (
  <LocalProvider localStore={localStore}>
    <h1>{'Dashboard'}</h1>
  </LocalProvider>
)
const DashboardRoute = () => (
  <Route path="dashboard" component={DashboardRoot} />
)
export default DashboardRoute

Now there are 2 different stores in context:

  • the global application store provided by the main app
  • the local module localStore provided in each module

So module components can access both stores, one using the normal connect and one using a localConnect.

The difference between the 2 Provider and connect are basically the name of the context object: store vs localStore.

Conclusions

If we agree on that, we might make Provider and connect somehow configurable to define the name of the store object, falling back to the default store.

I’d like to hear your thoughts now, whether this is a correct approach, whether I’m missing some piece of the puzzle or whether there are “better” alternatives.

Thanks! 😃

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:8
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

12reactions
emmenkocommented, Mar 24, 2016

I finally had the time to publish this as a library, in case someone is interested.

https://github.com/emmenko/react-redux-custom-store

6reactions
gaearoncommented, Mar 5, 2016

At this point there is a problem though. A store already exists in the context as it was defined by the root Provider of the main app.

Why is this a problem? A nested <Provider> will override the context supplied by the parent <Provider>. Context can be nested.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Face uncertainty by decoupling Redux state - Andrew Goldis
In this post I will try to show how decoupling and encapsulating Redux state can help us to deal with unpredicted changes while...
Read more >
What is decoupled architecture? | Definition from TechTarget
In general, a decoupled architecture is a framework for complex work that allows components to remain completely autonomous and unaware of each other....
Read more >
Decouple Application Components using Amazon SQS
In this article we are going to see how Amazon Simple Queue Service (SQS) helps you to build Event Driven Architecture, and how...
Read more >
Micro Frontend Architecture and Best Practices - XenonStack
Scalability: With the modular and decoupled micro frontends architecture, we can scale up an application to multiple teams as a new frontend ...
Read more >
Automate deployment of nested applications using AWS SAM
Using nested applications, you can rapidly build highly sophisticated serverless architectures by reusing services or components that are independently ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found