我有2个减速器组合在Root Reducer中,并在商店中使用。 第一个reducer'FisscksReducer'应该返回一个对象,第二个'FavoritesReducer'应该返回一个数组。
当我在connect中创建容器组件和mapStateToProps方法时,由于某种原因,存储的返回状态是一个对象,其中包含2个包含数据的reducer对象,而不仅仅是包含重叠数据的对象,如预期的那样。
function mapStateToProps(state) {
debugger:
console.dir(state)
//state shows as an object with 2 properties, AllTracksReducer and FavoritesReducer.
return {
data: state.AllTracksReducer.data,
isLoading: state.AllTracksReducer.isLoading
}
}
export default connect(mapStateToProps)(AllTracksContainer);
所以,在mapStateToProps中,为了获得正确的州财产,我不得不说 state.AllTracksReducer.data ...但是我期待数据直接在状态对象上可用?
答案 0 :(得分:8)
是的,这是一个常见的半错误。这是因为您可能正在使用ES6对象文字速记语法来创建传递给combineReducers
的对象,因此导入变量的名称也用于定义状态切片名称。
此问题在Redux文档中解释,位于Structuring Reducers - Using combineReducers
。
答案 1 :(得分:2)
创建一些接收整个状态(或特定于reducer的状态)的选择器,并在mapStateToProps
函数中使用它。实际上,当您combineReducers
时,您定义的名称将是最顶级的状态键,因此您的选择器应考虑到这一点:
const getTracks = (state) => state.allTracks.data
const isLoading = state => state.allTracks.isLoading
这假设您将缩减器与allTracks
组合在一起,因为它们的键如下:
combineReducers({
allTracks: allTracksReducer
})
然后您可以在映射器中使用这些选择器,例如
const mapStateToProps = state => ({
isLoading: isLoading(state),
tracks: getTracks(state)
})
您的combineReducers
电话和您的选择器之间存在微妙的联系。如果您更改状态键名称,则必须相应地更新选择器。
这有助于我将行动创作者视为"制定者"和选择器作为" getters",reducer函数只是持久性部分。当您想要修改状态时,可以调用您的setter(调度动作创建者),并使用所示的选择器获取当前状态并将其作为道具传递给组件。
答案 2 :(得分:0)
嗯,这就是它应该如何运作。当你使用combineReducers时,你实际上是将reducer的名称映射到reducer函数。
如果它困扰你,如果你使用es2016(虽然看起来你不是这样),我会建议一些语法魔法:
function mapStateToProps(state) {
const { data, isLoading } = state.allTracksReducer;
return {
data: data,
isLoading: isLoading
}
}
export default connect(mapStateToProps)(AllTracksContainer);
请记住,国家是拥有所有减刑者的真理之源。