您如何在React Redux容器中自定义调度?

时间:2018-08-17 15:25:16

标签: javascript reactjs redux react-redux

React Redux的构建方式要求您从mapDispatchToProps()函数内部调度更改。如果我想使用容器(将React组件连接到Redux的高阶组件)访问状态,而同时能够分派不同的动作*(取决于功能),我可以:

  1. 需要将所有功能的所有分配方式添加到正在访问状态的容器的mapDispatchToProps()函数中
  2. 需要为每个功能创建一个额外的容器,以包装正在访问状态的容器
  3. 需要通过回调道具将dispatch()暴露给该功能

是否存在建议的实现,以自定义上面列表中未分配的动作? 具体来说,为什么第三个选项会是一个错误的选择?

用例示例

我有一个React演示组件(VerticalBarChart)和一个React-Redux容器组件(VerticalBarChartContainer)。我想从状态相同的位置访问数据,但需要在用户不同地单击图表的条形时进行处理(取决于功能)。在功能A中,我希望我的功能像已钻取该条的数据一样工作,在功能B中,我只想在模式中显示有关该条数据的更多详细信息。

示例1(mapDispatchToProps()内部的所有分发变体)

<!-- Feature A -->
<VerticalBarChartContainer bar-click-action="drill" />

<!-- Feature B -->
<VerticalBarChartContainer bar-click-action="showDetailsModal" />

示例2(在每个功能中包装容器)

<!-- Feature A (contains a VerticalBarChartContainer) -->
<FeatureAVerticalBarChartContainer />

<!-- Feature B (contains a VerticalBarChartContainer) -->
<FeatureBVerticalBarChartContainer />

示例3(公开发布)

<!-- Feature A -->
<VerticalBarChartContainer 
   onBarClick={ (dispatch) => dispatch(action1()) } 
   />

<!-- Feature B -->
<VerticalBarChartContainer 
   onBarClick={ (dispatch) => dispatch(action2()) }
   />

2 个答案:

答案 0 :(得分:0)

一个好的经验法则是,容器应很少包含JSX或定义组件本身,而应仅将内部组件包装为HoC。在此基础上,我认为一个好的模式是通过创建多个包装相同内部表示组件的不同容器来产生行为,这是您上面的示例2。

答案 1 :(得分:0)

如果您要调度一个以状态和/或道具为条件的动作,则可以通过mergeProps的方法,该方法是connect的第三个参数。 mergeProps方法接收状态道具(从mapStateToProps返回的对象),调度道具(从mapDispatchToProps返回的对象)和组件道具。

这是一个用法示例(请不要省略mapStateToProps和mapDispatchToProps方法,因为我以为您很熟悉):

function mergeProps(stateProps = {}, dispatchProps = {}, ownProps = {}) {
  const { conditionA } = ownProps;
  const { conditionB } = stateProps;
  const { firstFn, secondFn } = dispatchProps;
  const onClick = (conditionA && conditionB) ? firstFn : secondFn;

  return {
    ...ownProps,
    ...dispatchProps,
    ...stateProps,
    onClick,
  };
}

export const ConnectedComponent = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps,
)(Component);