问题描述
我正在使用Redux和React创建一个应用程序。我遇到了一个问题,我无法将状态映射到组件属性,因为状态有一个与我使用的reducer名称相匹配的属性。
I am creating an app using Redux and React. I run into a problem where I cannot map state to component properties since the state has a property that matches the name of the reducer I used.
根减少器是用 combineReducers
method
The root reducer is created with combineReducers
method
const rootReducer = combineReducers({
appReducer
});
初始状态是
const initialState = {
sources: [],
left: {},
right: {},
diff: {}
}
但是在组件函数 mapStateToProps
中:
function mapStateToProps(state) {
return {
sources: state.sources
}
}
state.sources
是未定义
因为州
参数的值是
{
appReducer: {
sources: [],
left: {},
right: {},
diff: {}
}
}
这是redux的功能吗?所以当我使用更多reducers时,所有这些都将为 state
变量添加新属性?或者我的方面有什么问题(在redux教程中我从未注意到这种行为)。
Is this a feature of redux? So when I use more reducers, all of them will add new property to state
variable? Or is there something wrong on my side (I never noticed this behavior in redux tutorials).
谢谢
推荐答案
如果您只有一个reducer,则不需要 combineReducers()
。只需直接使用它:
If you only have a single reducer, you don’t need combineReducers()
. Just use it directly:
const initialState = {
sources: [],
left: {},
right: {}
}
function app(state = initialState, action) {
switch (action.type) {
case 'ADD_SOURCE':
return Object.assign({}, state, {
sources: [...state.sources, action.newSource]
})
case 'ADD_SOURCE_TO_LEFT':
return Object.assign({}, state, {
left: Object.assign({}, state.left, {
[action.sourceId]: true
})
})
case 'ADD_SOURCE_TO_RIGHT':
return Object.assign({}, state, {
right: Object.assign({}, state.right, {
[action.sourceId]: true
})
})
default:
return state
}
}
现在您可以使用该减速器创建商店:
Now you can create a store with that reducer:
import { createStore } from 'redux'
const store = createStore(app)
并将组件连接到它:
const mapStateToProps = (state) => ({
sources: state.sources
})
然而你的减速机是难以阅读,因为它一次更新许多不同的东西。现在,这个是您想要将其拆分为多个独立缩减器的时刻:
However your reducer is hard to read because it update many different things at once. Now, this is the moment you want to split it into several independent reducers:
function sources(state = [], action) {
switch (action.type) {
case 'ADD_SOURCE':
return [...state.sources, action.newSource]
default:
return state
}
}
function left(state = {}, action) {
switch (action.type) {
case 'ADD_SOURCE_TO_LEFT':
return Object.assign({}, state, {
[action.sourceId]: true
})
default:
return state
}
}
function right(state = {}, action) {
switch (action.type) {
case 'ADD_SOURCE_TO_RIGHT':
return Object.assign({}, state, {
[action.sourceId]: true
})
default:
return state
}
}
function app(state = {}, action) {
return {
sources: sources(state.sources, action),
left: left(state.left, action),
right: right(state.right, action),
}
}
这更容易维护和理解,也可以更容易地独立更改和测试减速器。
This is easier to maintain and understand, and it also makes it easier to change and test reducers independently.
最后,作为最后一步,我们可以使用 combineReducers()
来生成root app
reducer,而不是手工编写:
Finally, as the last step, we can use combineReducers()
to generate the root app
reducer instead of writing it by hand:
// function app(state = {}, action) {
// return {
// sources: sources(state.sources, action),
// left: left(state.left, action),
// right: right(state.right, action),
// }
// }
import { combineReducers } from 'redux'
const app = combineReducers({
sources,
left,
right
})
使用 combineReducers()没有大的好处
而不是手动编写根减速器,除了它稍微有点效率,可能会省去一些拼写错误。此外,您可以在应用程序中多次应用此模式:将不相关的Reducer以嵌套方式多次组合到单个reducer中可以。
There is no large benefit to using combineReducers()
instead of writing the root reducer by hand except that it’s slightly more efficient and will likely save you a few typos. Also, you can apply this pattern more than once in your app: it’s fine to combine unrelated reducers into a single reducer several times in a nested way.
所有这些重构都会对组件没有影响。
All this refactoring would have no effect on the components.
我建议你观看我的,涵盖了 reducer composition 的这种模式,并展示了如何实现 combineReducers()
。
I would suggest you to watch my free Egghead course on Redux which covers this pattern of reducer composition and shows how combineReducers()
is implemented.
这篇关于redux / react app中的状态具有属性为reducer的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!