【问题标题】:How to organise "sub-applications" with redux?如何用 redux 组织“子应用程序”?
【发布时间】:2016-03-31 11:20:12
【问题描述】:

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

const appState = {
    subApps: [],
};

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

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

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

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

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

    更新:

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

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

    【讨论】:

    • 嗯,看起来 Dan Abramov 听到了你的建议并提出了解决方案:twitter.com/dan_abramov/status/716217178731765762
    • 是的,解决方案看起来一样。我会将此链接添加到我的答案中。
    • @CPHPython react-hot-loader 与 Redux 无关,它不会帮助 OP 解决他们的具体问题
    • @ClementParis016 感谢您的注意,不知何故这对我来说是有意义的(模块VS子应用程序?也许我的评论是对这个解决方案的补充?现在不知道......)。无论如何,hot-loader 已被弃用,fast-refresh 是替代品,它旨在重新加载模块(也许子应用具有相同的模块导入?)。我也可以删除这条评论以减少熵。
    【解决方案2】:

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

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

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

    大应用

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 同意,所有关于通过引入子减速器来简化状态管理
      • 不幸的是,这是不可能的,因为所有的堆栈都是动态添加的。堆栈的数据甚至可以从数据库中加载,所以我事先并不知道所有的键。
      • 好的,我明白了。但是如果你想修改每一个加载的子App的状态,你必须提前知道这个状态的结构和更新它的方式(具体的reducer),对吧?因此,也许您可​​以使用每个潜在的 subApp 状态类型初始化整个应用程序状态,然后在加载时激活 subApp 类型状态中的标志
      • 感谢您的回复。我什至不知道潜在的 subApp 类型,有时,它们也可以动态创建(它们可能会获得一些 UID)。我在考虑几个选项: - 多个商店 - 根本不要在子应用中使用容器,只使用道具 - 我已经看到有类似高阶商店的东西,但老实说,还没有调查,不能找不到有关此的适当文档。 - 可以用于多个组件,然后我可以将适当的存储映射到每个子应用程序。然后当我执行mapStateToProps(state) 时,状态可能是“本地”状态。
      • 您不需要知道这些键 - 这个例子说明了这一点 redux.js.org/docs/advanced/ExampleRedditAPI.html 。它存储 subreddit 数据,它不知道您将访问哪个 subreddit。它动态地将键添加到存储中。
      猜你喜欢
      • 1970-01-01
      • 2017-12-03
      • 2011-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2011-02-12
      相关资源
      最近更新 更多