React 组件OilBarrel
连接了我的 redux 商店以创建容器OilBarrelContainer
:
// ---- component
class OilBarrel extends Component {
render() {
let data = this.props.data;
...
}
}
// ---- container
function mapStateToProps(state) {
let data = state.oilbarrel.data;
...
}
const OilBarrelContainer = connect(mapStateToProps)(OilBarrel)
// ---- reducer
const oilbarrel = (state = {}, action) => {
let data = state.data;
}
const storeFactory = (server = false, initialState = {}) => {
return applyMiddleware(...middleware(server))(createStore)(
combineReducers({oilbarrel, otherReducer1, otherReducer2}),
initialState
)
}
我觉得很奇怪mapStateToProps()
收到顶级状态对象(应用程序的整个状态),要求我遍历state.oilbarrel.data
,当reducer(方便地)只接收到分支时属于此组件的状态。
这限制了重用此容器的能力,而不知道它在何处适合状态层次结构。我做错了我的mapStateToProps()
正在接收完整状态吗?
答案 0 :(得分:2)
这不是故意的,因为您可能希望在组件中使用状态的其他部分。一个选项是将选择器(mapStateToProps)保存在与组件不同的文件中,这将有助于您重用选择器,如果您的应用程序非常庞大且复杂,您还可以检出诸如重新选择之类的库,这有助于提高选择器的效率
答案 1 :(得分:2)
这是mapStateToProps
行为。您必须将redux状态视为单一的事实来源(顺便说一句,就是它的真实情况),而与项目中的组件无关。没有出路,您必须知道状态中特定数据的确切层次结构,以将其传递给容器组件。
答案 2 :(得分:2)
Dan Abramov在Colocating Selectors with Reducers下的高级redux课程中为此提供了解决方案。
这个想法是,对于每个reducer,都有一个选择器,而选择器只知道它的reducer结构。更高级别减速器的选择器,包含较低级别的减速器,以及它们的一部分状态,等等。
该示例取自课程github:
在todos reducer文件中:
export const getVisibleTodos = (state, filter) => {
switch (filter) {
case 'all':
return state;
case 'completed':
return state.filter(t => t.completed);
case 'active':
return state.filter(t => !t.completed);
default:
throw new Error(`Unknown filter: ${filter}.`);
}
};
在主reducer文件中:
export const getVisibleTodos = (state, filter) =>
fromTodos.getVisibleTodos(state.todos, filter);
现在你可以在不知道结构的情况下获得你所在州的每个部分。但是,它增加了很多样板。