Как добиться повторного использования кода, если мы используем React Redux Hooks? - PullRequest
0 голосов
/ 15 марта 2020

Допустим, у нас есть компонент:

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>
  );
}

Предположим, что это действительно сложный компонент, и вместо 3 строк кода внутри return () имеется 45 или 80 строк кода. В таком случае, как нам добиться повторного использования кода, если мы не хотим повторять код, если нам нужно сопоставить этот компонент с другим состоянием Redux?

Например,

  1. что если нам понадобятся два таких компонента на одной странице, один для countIceCream и один для countDrink?
  2. , если на странице заказа To Go нам нужен такой компонент, но он предназначен для countSpoon?

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Если я правильно понимаю, вы хотите произвести один и тот же вывод, но получить данные о состоянии из разных мест для CountIceCream и CountDrink. Также действия различны для CountIceCream и CountDrink.

Итак, вот пример действия приращения для CountIceCream и CountDrink:

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

Вот селекторы для получения данных подсчета для напитка и льда cream (это простой пример, в проектах я бы посоветовал использовать компонуемые селекторы для предотвращения дублирования)

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
    );
  }
);
1 голос
/ 15 марта 2020

я сделаю два компонента: Первый IceCreamCount или DrinkCount, а второй - базовый c 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={...} />
}
...