如果我们使用 React Redux Hooks,我们如何实现代码重用?

How to we achieve code-reuse if we use React Redux Hooks?

假设我们有一个组件:

function Count() {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  const increment = () => dispatch({ type: 'INCREMENT' });
  const decrement = () => dispatch({ type: 'DECREMENT' });

  return (
    <div>
      <button onClick={increment}> + </button>
      {count}
      <button onClick={decrement}> - </button>
    </div>
  );
}

假设它实际上是一个复杂的组件,而不是 return () 中的 3 行代码,而是 45 或 80 行代码。那么,如果我们需要将这个组件映射到不同的 Redux 状态,如果我们不想重复代码,我们如何实现代码重用?

例如,

  1. 如果我们在同一页面上需要两个这样的组件,一个用于 countIceCream,一个用于 countDrink,该怎么办?
  2. 如果在 To Go Order 页面上,我们需要这样的组件,但它用于 countSpoon?

我要做的是 制作两个组件,第一个 IceCreamCountDrinkCount 第二个是基本的 Count 组件,不会连接到 redux

示例:

function Count(props){
     return (
    <div>
      <button onClick={props.increment}> + </button>
      {props.count}
      <button onClick={props.decrement}> - </button>
    </div>
  );
}


//connected to redux
function IceCreamCount(props){
    return <Count count={props.count} increment={...} decrement={...} />
}

如果我理解正确的话,您希望生成相同的输出,但从不同位置获取 CountIceCream 和 CountDrink 的状态数据。 CountIceCream 和 CountDrink 的操作也不同。

下面是 CountIceCream 和 CountDrink 的增量操作示例:

const incrementDrink = ()=>({type;INCREMENT_DRINK})
const incrementIceCream = ()=>({type;INCREMENT_ICE_CREAM})

这里是获取饮料和冰淇淋计数数据的选择器(这是一个简单的例子,在项目中我建议使用 composable selectors 来防止重复)

const selectIceCreamCount = state => state.iceCream.count;
const selectIceDrinkCount = state => state.drinkCream.count;

您的容器可能如下所示:

const CounterContainer = function CounterContainer(
  { selector, up, down, remove },
  props
) {
  const dispatch = useDispatch();
  const count = useSelector(selector);
  const propsForPresentational = {
    count
    increment: () => dispatch(incement),
    decrement: () => dispatch(decrement),
    ...props,
  };
  //a container should not return jsx, 
  //  better create a presentational component instead      
  return <div>bunch of jsx</div>
};

以下是创建冰淇淋计数容器的方法:

export const IceCreamCountContainer = React.memo(
  function IceCreamCountContainer(props) {
    return CounterContainer(
      {
        selector: selectIceCreamCount,
        increment:incrementIceCream,
        decrement:decrementIceCream,
      },
      props
    );
  }
);