我有react组件使用redux。这是一个带有侧边栏和主视图区域的视图。
当我想创建一个新视图时,我可以继承这个基视图。所有可能的动作都在reducer中共享。
唯一的问题是,当一个动作被调度时,我需要命名这个动作,这样商店就有了更多的上下文,视图调用这个动作。即使动作类型是相同的。
我想我可以有一个视图数组,并使用它来循环具有动态命名空间的操作类型。我想我的语法错了。或者是我的想法错了。
我在想我可以循环一个开关情况-我知道这现在将返回多个状态重写自己。所以显然不太好。
考虑如何干净利落地处理这个操作
const views = [{name: 'visitor', actionName: 'VISITOR'},{name: 'action', actionName: 'ACTION'}]
const reducer = (state, action) => {
views.forEach((view, i) => {
switch (action.type) {
// View Actions
case view.actionName + '_VIEW_LOADED':
return {
...state,
['open_' + view.name + '_view']: true,
[view.name + '_props']: action[view.name + '_view_data']
}
default:
return state;
}
});
}
这是讨论组合胜过继承的最佳时机。如果这个概念对你来说是全新的,请观看这个视频。
在我看来,你的公共视图组件应该是你的其他组件"扩展"它的子组件(也许是唯一的子组件)。然后,你可以把公共视图组件应该使用的特定动作创建器传递给props。
/* Common View Component */
class CommonSplitView extends React.Component {
...
render() {
return (
<button onClick={this.props.onCloseDetailView}>Close</button>
<button onClick={this.props.onOpenDetailView}>Open</button>
);
}
}
CommonSplitView.propTypes = {
onCloseDetailView: React.PropTypes.func,
onOpenDetailView: React.PropTypes.func
}
/* Component that extends the common view component */
class ProfileView extends React.Component {
...
render() {
return (
<CommonSplitView
onCloseDetailView={this.props.onCloseDetails}
onOpenDetailView={this.props.onOpenDetails}
/>
);
}
}
...
const mapStateToProps = state => state;
const mapDispatchToProps = dispatch => ({
onCloseDetails: () => { dispatch(<something specific to ProfileView>) },
onOpenDetails: () => { dispatch(<something specific to ProfileView>) }
});
export default connect(mapStateToProps, mapDispatchToProps)(ProfileView);
Ta哒!就像那样,现在你的公共视图组件(在这个例子中是CommonSplitView)分派特定于ProfileView的操作。很简洁,对吧?这称为控制反转。从父组件中,我注入了我希望CommonSplitView在点击Close和Open按钮时调用的方法。事实证明,这种模式在任何地方都非常方便。
希望这有帮助。好运!