В этой короткой статье я расскажу о стиле функционального программирования React и особенно о хорошо известной библиотеке под названием перекомпоновка.

Перекомпоновка - это хорошо, но непросто для новичков

Мне вообще нравится перекомпоновка, и я бы использовал его для своего личного проекта. Однако иногда мне кажется, что новичкам это нелегко. Может потребоваться некоторое время, чтобы привыкнуть к функциональному стилю программирования и полюбить его заново.

Например, compose допускает следующий код.

const hoc1 = ...;
const hoc2 = ...;
const enhance = compose(hoc1, hoc2);
const Component = enhance(BaseComponent);

Иногда это сбивает с толку людей, которые не привыкли работать с композицией. То же самое можно сделать и со следующим.

const Component = hoc1(hoc2(BaseComponent));

Это может выглядеть некрасиво, особенно если у нас более двух HoC, но это интуитивно понятно. Конечно, перекомпоновка не запрещает такой стиль написания, поэтому разработчики должны решать, как писать код. Пример кода с compose может показаться волшебством для новичков, хотя основная часть реализации compose довольно проста.

const compose = funcs => funcs.reduce((p, c) => (...args) => p(c(...args))); // this only works if funcs.length >= 2

Я думаю, новичкам было бы проще использовать функциональные композиции без compose, а затем, когда они к этому привыкли, ввести compose. В этом смысле compose необязательно включать в пакет.

Другой пример - withStateHandler. Это можно использовать следующим образом.

const hoc = withStateHandlers(
  ({ initialCounter = 0 }) => ({ counter: initialCounter }),
  {
    increment: () => ({ counter }) => () => ({ counter: counter + 1 }),
  }
);
const BaseComponent = ({ counter, increment }) => (
  <div>
    <span>{counter}</span>
    <button onClick={increment}>Click Me</button>
  </div>
);
const Component = hoc(BaseComponent);

Это легко понять, если вы поймете, как handlers работает. Альтернативный способ следующий.

const hoc = withState('counter', 'setCounter', 0);
const BaseComponent = ({ counter, setCounter }) => {
  const increment = () => setCounter(counter + 1);
  return (
    <div>
      <span>{counter}</span>
      <button onClick={increment}>Click Me</button>
    </div>
  };
};
const Component = hoc(BaseComponent);

Думаю, для новичков это может быть проще. Я считаю, что recompose предоставляет слишком много функций.

Более простые пакеты

Вот несколько пакетов, которые я разработал. Это очень простые пакеты, и вы можете изучить их, прочитав исходный код.

Пока этих пакетов мне достаточно, чтобы создать небольшое приложение для реагирования только с функциональными компонентами. Нам может потребоваться больше функций для создания большего приложения, и тогда мы разработаем для него другой более простой пакет.

Некоторым читателям следует заметить, что мы можем сделать то же самое с recompopse, не вводя эти новые пакеты. Это правильно. Речь идет только о стиле программирования, а не о пакетах. Так что я бы не стал создавать другие пакеты, если функциональность действительно такая же. Например, я бы просто использовал pure из recompose.

Тем не менее, я надеюсь, что эти более простые пакеты помогут некоторым разработчикам, которым трудно учиться recompose.