如何用 redux 组织 "sub-applications"?

How to organise "sub-applications" with redux?

我正在开发一个相当大规模的应用程序,如果能从您那里得到一些建议,我将不胜感激。 我在 react-redux <Provider> 中有一个应用程序包装器,它有子应用程序列表。

const appState = {
    subApps: [],
};

子应用程序非常复杂,将它们的一些组件用作容器会很方便,因此使用 mapStateToPropsmapDispatchToProps。但是,使用mapStateToProps是不行的,因为store是根对象,我们不知道当前子应用在appState.

中的索引是什么

将来我计划将这些子应用程序分开,然后放入自己的网络工作线程中。在这种情况下,也许可以使用多个商店并将商店发送到主线程并将其作为主商店的一部分?

有很多方法可以处理这种情况,基本上,问题是如何用 redux 框架处理子应用程序之类的东西。也许你们中有些人遇到过类似的问题,或者只是知道如何以最好的方式解决问题。

稍微不同的全局应用程序状态结构对您有帮助吗?例如:

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

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

另一方面,如果您的子应用程序完全独立于父应用程序,您可以让他们使用他们想要的任何结构(例如,他们自己的 redux 存储,不同于父应用程序)和只需将它们集成到 React 包装器组件中,就像这样:

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>
        );
    },
});

似乎在这种情况下,最好的解决方案是用 <Provider> 包装每个子应用程序,并为每个容器传递自己的商店。我们还可以使用 react-redux-custom-store 库来创建具有自定义名称的商店。

更新:

丹·阿布拉莫夫推特:https://twitter.com/dan_abramov/status/716217178731765762

示例: https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400

Redux 文档现在有关于此的信息,请参阅

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

简而言之,您可以将这些子应用程序视为拥有自己商店的私有应用程序。它们将被包装在挂接到该特定商店的 <Provider> HOC 中。

BigApp

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

子应用程序

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>
    )
  }
}