Dan Abramov的这个tutorial表明,使用作用于全局状态(而不是状态片段)的选择器的优点是它们允许容器与状态结构的知识分离。
如果是这种情况,我们是否应该避免直接将状态值映射到props,而是使用选择器?否则,我们的容器仍然必须知道状态树中存在这些值的位置。
使用示例来说明......
直接将嵌套状态值映射到prop:
const mapStateToProps = (state) => ({
isModalVisible: state.modal.isVisible,
});
VS
不了解州的结构。使用isModalVisible()
选择器获取值:
const mapStateToProps = (state) => ({
isModalVisible: isModalVisible(state),
});
然而,后一种方法的问题是对于状态树中的每个值,我们必须编写一个选择器。这似乎是很多样板代码只是为了选择一个简单的值。这被认为是最佳做法吗?
答案 0 :(得分:7)
你的问题的答案是:“这取决于”
你有一个小应用程序吗?
可能完全避免使用redux并坚持反应组件状态。
你有一个小应用程序吗?
编写一堆选择器就像你说的那样是很多样板。避免使用mapStateToProps
编写它们并坚持简单映射。
大中型应用
这是选择器和记忆选择器的回报。你会发现自己检查模态是否在许多组件中可见。目前,您的州模态位于state.modal.visible
之下。但是明天模态可能是父模式的一部分,您必须将所有组件中的所有映射更改为state.parentModal.modal.visible
。你可以看到这怎么可能变得非常糟糕?
选择者的优点:
mapPropsToState
函数上编写过滤器和减少列表。备忘选择器的优点:
<强>缺点强>
希望它能回答你的问题。
答案 1 :(得分:3)
回应您的上一条评论,是的,建议为树中的所有值编写选择器,即使是简单的非派生值。
这样做的几个原因:
正如我在评论中提到的,一旦您对所有值使用选择器,您可以根据需要修改树结构,然后您只需相应地修改选择器。否则,您和您的共同开发人员必须手动修改每个直接映射,即使它是非衍生数据。
在树中的不同级别之间解耦值。就像你说的那样,当你有一个全局级选择器时,它依赖于一个切片级选择器,例如price
内的product
。当您将产品放到树中的其他位置时,只需修改product
选择器,所有全局级选择器price
仍然可以。我不确定Dan在他的教程中提到过,请查看此库reselect。它显示了关卡之间的想法。
获取计算数据时的效率。
如果你正在做一个小项目或从树中检索简单的非派生值,你可以使用直接映射。但请记住,广泛应用选择器会使您的代码可扩展。
答案 2 :(得分:3)
mapStateToProps
是选择器。您不需要为isModalVisible
编写单独的函数。这个想法是mapStateToProps
是唯一需要知道全局状态结构的函数。你可以根据需要细分该功能,特别是当子选择器变得更复杂时,但如果你所做的只是选择一个简单的值,那么就没有必要这样做。
因此,容器组件不知道状态结构。它只知道mapStateToProps
返回的值的结构。你的两个例子在功能上是等价的,因为它涉及问题&#34;容器应该知道状态结构吗?&#34;。因为在这两种情况下,答案都是&#34;他们不会。&#34;
答案 3 :(得分:1)
不要将本地状态与全局状态(redux存储)混合。您可以同时拥有组件,但本地状态不应该依赖于全局状态。
这是由于以下原因: