redux/react 应用程序中的状态有一个带有化简器名称的属性
State in redux/react app has a property with the name of the reducer
我正在使用Redux和React创建一个应用程序。我遇到了一个问题,我无法将状态映射到组件属性,因为状态具有与我使用的化简器名称匹配的属性。
根化简器是用combineReducers
方法创建的
const rootReducer = combineReducers({
appReducer
});
初始状态为
const initialState = {
sources: [],
left: {},
right: {},
diff: {}
}
但是在组件函数中mapStateToProps
:
function mapStateToProps(state) {
return {
sources: state.sources
}
}
state.sources
undefined
,因为state
参数的值为
{
appReducer: {
sources: [],
left: {},
right: {},
diff: {}
}
}
这是 redux 的一个功能吗?那么当我使用更多的化简器时,它们都会state
变量添加新属性吗?还是我这边出了什么问题(我从未在 redux 教程中注意到这种行为)。
谢谢
如果你只有一个减速器,你不需要combineReducers()
。直接使用即可:
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
}
}
现在,您可以使用该化简器创建商店:
import { createStore } from 'redux'
const store = createStore(app)
并将组件连接到它:
const mapStateToProps = (state) => ({
sources: state.sources
})
但是,您的减速器很难阅读,因为它一次更新许多不同的内容。现在,这是您想要将其拆分为几个独立化简器的时刻:
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),
}
}
这更容易维护和理解,也更容易独立更换和测试减速器。
最后,作为最后一步,我们可以使用 combineReducers()
生成根app
化简器,而不是手动编写:
// 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()
而不是手动编写根化简器没有太大的好处,除了它的效率稍微高一些,并且可能会为您节省一些拼写错误。此外,您可以在应用中多次应用此模式:可以以嵌套方式将不相关的化简器多次组合到单个化简器中。
所有这些重构都不会对组件产生影响。
我建议您观看我在Redux上的免费Egghead课程,该课程涵盖了这种减速器组合模式,并展示了combineReducers()
是如何实现的。
实际上,我相信您的初始状态是:
{
appReducer: {
sources: [],
left: {},
right: {},
diff: {}
}
}
这是因为combineReducers
通过采用化简器的名称并将其内容映射到该名称来工作。
另外,只是一个注释,但是如果您要使用多个化简器,则化简器的名称应该比appReducer
更具体,并且(仅我个人的意见)它们不需要reducer
这个词。典型的应用可能如下所示:
combineReducers({
user: userReducer,
messages: messagesReducer,
notifications: notificationsReducer
});
然后,可以像以下方式访问您的状态:
state.user.email
state.messages[0]
- redux/react 应用程序中的状态有一个带有化简器名称的属性
- 如果我有一个指向所需属性的路径数组,如何设置为对象的属性
- 我有一个由100个具有类别和子类别属性的对象组成的数组,需要创建一个新的子类别计数数组
- 如果至少有一个选定项目具有自定义属性,如何隐藏HTML5分隔符
- 如果有一个名为“”的子输入,我如何获得form.method属性值;方法”;
- 如何获得一个属性的值在javascript中有一个点在它的名字
- 是否有一个事件来检测是否在Javascript中设置了属性
- 引导词缀属性在标题下面有一个固定的导航
- 一个javascript对象可以有一个属性是另一种类型对象的集合吗?
- 在返回字符串的getter上有一个隐藏属性
- 是否有一个现有的或即将推出的CSS3选择器来匹配属性名的子字符串
- 是否有一个(polyfill)代码重置所有继承的CSS属性上的给定元素
- 如果一个数组有一个属性,则查找同一数组的另一个属性的值
- 是否有一个“不在”操作符在JavaScript检查对象属性
- 是否有一个简单的方法来获得javascript对象中所有键的属性
- 是否有一个jquery函数来列出属性
- select元素有一个标准值属性
- 为什么每个JS对象都有一个未定义的属性?
- 哪些对象在JavaScript有一个.length属性?(又名为什么下划线_.每个都把我的函数对象当作数组?)
- 为什么会有一个'amd'属性在'define'作用