Ross Khanas
Ross Khanas

Reputation: 1501

How to organise "sub-applications" with redux?

I'm working on a pretty large-scale application and would be thankful to get some suggestions from you. I have an application wrapper in react-redux <Provider> and it has list of sub-applications.

const appState = {
    subApps: [],
};

Sub-apps are pretty complicated and it would be convenient to use some of their components as a containers, so use mapStateToProps and mapDispatchToProps. However, using mapStateToProps is not possible, because store is a root object, and we don't know what is the index of current sub-app in appState.

In future I plan separating these sub-apps and put then into own web-worker thread. In this case maybe it is ok to use multiple stores and send stores to the main thread and have it as a part of main store?

There are a lot of approaches how to handle this situation, basically, the problem is how to handle something like sub-applications with redux framework. Maybe some of you faced similar problem, or just know the solution how to solve in the best way.

Upvotes: 5

Views: 5041

Answers (3)

aug
aug

Reputation: 11714

Redux documentation now has information about this see

https://redux.js.org/recipes/isolatingsubapps

In a nutshell, you can treat these subapps as their own private apps with their own stores. They will be wrapped in the <Provider> HOC that is hooked into that specific store.

BigApp

import React, { Component } from 'react'
import SubApp from './subapp'
​
class BigApp extends Component {
  render() {
    return (
      <div>
        <SubApp />
        <SubApp />
        <SubApp />
      </div>
    )
  }
}

SubApp

import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from './reducers'
import App from './App'
​
class SubApp extends Component {
  constructor(props) {
    super(props)
    this.store = createStore(reducer)
  }
​
  render() {
    return (
      <Provider store={this.store}>
        <App />
      </Provider>
    )
  }
}

Upvotes: 4

Ross Khanas
Ross Khanas

Reputation: 1501

Seems like in this case the best solution is to wrap each subApp with <Provider> and pass own store for each container. We can also use react-redux-custom-store library to create stores with custom names.

Update:

Dan Abramov twitt: https://twitter.com/dan_abramov/status/716217178731765762

Example: https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400

Upvotes: 4

pierrepinard_2
pierrepinard_2

Reputation: 1426

Would a slightly different structure of global app state help you? For example:

const appState = {
    subApps: {
        subApp1: {},
        subApp2: {},
        // etc.
    },
    currentSubApp: 'subApp2',
};

const subApp2State = appState.subApps[appState.currentSubApp];

On the other hand, if your subApps are completely independent of the parent-app, you could let them use whatever structure they want (their own redux store for example, different from the one of the parent-app) and simply integrate them in React wrapper-components, like this:

import SubApp from '...anywhere...';

const SubAppWrapper = React.createClass({
    componentDidMount: function() {
        this.subApp = new SubApp({
            containerElement: this.refs.containerDiv,
            // other params
        });
    },

    componentWillUnmount: function() {
        this.subApp.destroy();
    },

    render: function() {
        return (
            <div ref="containerDiv"></div>
        );
    },
});

Upvotes: 1

Related Questions