我想制作可以插入任何react-redux应用程序的可重用模块 . 理想情况下,我的模块在顶层有一个容器组件,操作和reducer(然后是容器下面的任何表示组件) . 我希望模块只能处理自己应用程序状态的一部分,理想情况下不必了解应用程序状态的其余部分(因此它是真正的模块化) .
Reducers只能在部分状态下工作(使用combineReducers),所以我很高兴 . 但是,对于容器组件,mapStateToProps似乎总是处于应用程序的完整状态 .
如果mapStateToProps只接受我在模块中处理的相同“状态切片”(就像reducer一样),我会喜欢它 . 这样我的模块就会真正模块化 . 这可能吗?我想我可以把状态的那一部分传递给这个组件的道具(所以我可以使用mapStateToProps的第二个参数,ownProps),但我不确定这是否具有相同的效果 .
6 回答
这实际上是一个复杂的话题 . 因为Redux是一个单一的全局存储,所以完全封装,完全可重用的即插即用逻辑集的想法确实变得相当困难 . 特别是,虽然reducer逻辑可以相当通用并且不知道它在哪里,但是选择器函数需要知道树中的哪个位置才能找到该数据 .
你问题的具体答案是“不,
mapState
总是给出完整的状态树” .我确实有许多相关资源的链接,这可能对您的情况有所帮助:
有几个现有的库试图实现"per-component state in Redux" . 我在我的Redux插件目录中有一个列表,在Component State类别中 .
一群开发人员一直在讨论和原型化各种方法 . 他们的工作是在https://github.com/slorber/scalable-frontend-with-elm-or-redux .
Randy Coulman最近发布了一个由三部分组成的博客系列,内容涉及Redux中的状态封装和模块化 . 他没有提出明确的答案,但这些帖子值得一读:Encapsulating the Redux State Tree,Redux Reducer Asymmetry和Modular Reducers and Selectors .
如你所知,Redux只有一个商店,所以它知道要做的就是将整个商店传递给你的mapStateToProps函数 . 但是,使用对象解构,您可以指定所需的存储中的哪些属性,而忽略其余属性 . 像'function mapStateToProps({prop1,prop2})'这样的东西只能捕获商店中的那两个属性而忽略其余的属性 . 您的功能仍在接收整个商店,但您只是指出这些道具只对您感兴趣 .
在我的例子中,'prop1'和'prop2'将是你在'combineReducers'调用期间为reducers指定的名称 .
理想情况下,它的工作方式是获取状态,然后使用解构器从中提取值 . redux适用于单一状态的概念
例如:-
我遇到了同样的问题,因为正如你所说,redux / react-redux的当前实现允许在状态上拆分reducers,但mapDispatchToProps总是传递整个状态树 .
https://stackoverflow.com/a/39757853/444794不是我想要的,因为这意味着我们必须在使用我们模块的每个react-redux应用程序中复制所有选择器逻辑 .
我目前的解决方法是将状态切片作为支柱传递下去 . 这遵循一种组成模式,但同时消除了直接进入国家的清洁,我对此感到失望 .
例:
通常,您想要这样做:
但由于此模块包含在一个应用程序中,其中状态现在是几个事物(即键值)而不是项目列表,这将不起作用 . 我的解决方法看起来像:
使用该模块的应用程序如下所示:
虽然
mapStateToProps
(您传递给连接的第一个函数)按照您的说法传递给整个商店,但它的工作是将状态的特定部分映射到组件 . 因此,只有从mapStateToProps返回的内容才会被映射为组件的prop .所以,让我们说你的州看起来像这样:
并且您的组件需要来自
account
和foo
的所有内容,然后您的mapStateToProps
将如下所示:然后你的组件将从你的redux映射prop
account
和foo
州 .你的问题的答案是肯定的 . 给出的答案都涵盖同一事物的不同方面 . 首先,Redux创建了一个包含多个reducer的商店 . 所以你会想要将它们组合起来:
然后,假设您有一个DepartmentsList组件,您可能只需要将
departments
从商店映射到您的组件(也可能是映射到props的一些操作):然后在组件内部基本上是: