redux/react 应用程序中的 state 有一个带有 reducer 名称的属性
Posted
技术标签:
【中文标题】redux/react 应用程序中的 state 有一个带有 reducer 名称的属性【英文标题】:State in redux/react app has a property with the name of the reducer 【发布时间】:2016-06-10 14:47:40 【问题描述】:我正在使用 Redux 和 React 创建一个应用程序。我遇到了一个问题,我无法将状态映射到组件属性,因为状态具有与我使用的减速器名称匹配的属性。
根reducer是用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 的一个特性吗?所以当我使用更多的reducer时,它们都会向state
变量添加新属性?还是我这边有什么问题(我从未在 redux 教程中注意到这种行为)。
谢谢
【问题讨论】:
你的代码是正确的state.appReducer. sources
你需要reducer名字
假设你有 2,3 个 reducer,每个 reducer 都有 sources
属性
你可以通过state.appReducer. sources
和`state.appReducer.2 sources`获取具体的sources
你所描述的是combineReducers
所做的一部分。
您需要在 appReducer 中设置“state = initialState.sources”来更新/访问特定状态
【参考方案1】:
如果你只有一个 reducer,你就不需要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
现在您可以使用该 reducer 创建一个商店:
import createStore from 'redux'
const store = createStore(app)
并将组件连接到它:
const mapStateToProps = (state) => (
sources: state.sources
)
但是,您的 reducer 很难阅读,因为它会同时更新许多不同的内容。现在,this 是您想要将其拆分为多个独立减速器的时刻:
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),
这样更容易维护和理解,也更容易独立更改和测试reducer。
最后,作为最后一步,我们可以使用combineReducers()
来生成根app
reducer,而不是手写:
// 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。
所有这些重构都不会对组件产生影响。
我建议您观看我的free Egghead course on Redux,它涵盖了这种reducer 组合 模式,并展示了combineReducers()
是如何实现的。
【讨论】:
感谢 Dan 的解释以及这些视频的链接。【参考方案2】:其实我相信你的初始状态应该是:
appReducer:
sources: [],
left: ,
right: ,
diff:
这是因为combineReducers
通过获取reducer 的名称并将其内容映射到该名称来工作。
另外,请注意,但如果您要使用超过 1 个减速器,则减速器的名称应该比 appReducer
更具体,并且(只是我个人的看法)它们不需要这个词reducer
。一个典型的应用程序可能如下所示:
combineReducers(
user: userReducer,
messages: messagesReducer,
notifications: notificationsReducer
);
然后,您的状态可以通过以下方式访问:
state.user.email
state.messages[0]
【讨论】:
你是对的。然后我应该相应地更改initialState
对象吗?
这个想法是reducer的每个分支都负责自己的initialState
。你的根减速器应该没有初始状态,每个减速器应该只包含它的东西。所以你的appReducer
将是一个带有源、左、右等键的对象。以上是关于redux/react 应用程序中的 state 有一个带有 reducer 名称的属性的主要内容,如果未能解决你的问题,请参考以下文章
最易懂的 redux (react-native state管理神器)
react状态管理器(分模块)之redux和redux + react-redux + reducer和redux + react-redux + reducer分模块 + 异步操作redux-thu