Как использовать redux без react
Возможно ли без Redux?
На сегодняшний день можно найти уйму позиций, где требуется react/redux. React прекрасен, вопросов нет. Вопрос к Redux — возможно ли без него. Если погуглить чуть-чуть, найдется добротная статья на Хабре, где автор задается таким же вопросом. В статье на простом примере (todoList) метод this.updateViews() вызывается слишком часто (семь-восемь раз) и кажется, что можно сделать проще.
Основная идея тут observable models, react отвечает за observable, дело осталось за малым — создать model.
Перед созданием модели пару слов о дизайне (архитектуре) клиента:
index — raw data
history — array[model]
observer — model
view — errors, focus, flags
index.jsx — точка входа программы для экрана пользователя. Index отрисовывает все компоненты с данными по умолчанию, делает асинхронные запросы, перерисовывает компоненты с новыми данными.
Observer.jsx отвечает за синхронизацию модели для нескольких views. Например, Петя заполняет форму для оффера и в шапке страницы видит real-time preview. Observer хранит объект модели, предоставляя дочерним компонентам api: onModelChange(field, value).
History.jsx — это stack объектов модели, где api: commit и rollback.
Model.js — это то, что пользователь может ввести ручками,— то есть самое ценное. Другие данные в модели хранить не нужно. Model — это не react компонент, а обычный js class.
Конструктор копирования как минимум нужен для History. Метод isEqual — для popup-unsaved-changes (что гораздо удобнее флага в state). Метод fieldNameConstrains — для зависимых полей.
Грубо говоря, если есть зависимые поля, их нужно изменять всем скопом.
По личному опыту, что-то типа model.field.onchange не работает, так как иногда нужно вызвать конструктор копирования и onchange события совсем не нужны.
Валидация. Валидацию не нужно делать в модели. Ее нужно проводить во view (не забываем, что view это экран пользователя и что на экране может быть показана не вся модель). Валидаторы это набор предикатов. Для валидации есть всего два алгоритма: 1) находим все ошибки в форме или 2) находим первую ошибку. Например,
Права доступа. Тут главное удержаться и не использовать наследование. Идея такая, что модель содержит все поля и мы урезаем поля под роли. То есть это whitelist, остальные поля в модели остаются по умолчанию. Для валидации добавляется один шаг — делаем проекцию объекта валидации (он же mapper, см. выше), то есть валидируем только нужные поля.
О продакшне. Данный подход крутится в продакшне уже год — это интерфейс для создания рекламных кампаний, включая баннеры. Формы разной сложности — начиная от одной модели на экран, заканчивая множеством моделей разных типов. Тут можно добавить, что бэкенд любит присылать вложенные структуры, нужно не стесняться и хранить только плоские структуры во view.
O методе модели isEqual. Где-нибудь в utils.js будут методы isEqual и isEqualArray:
Нужно стараться не делать модели вложенными. Не забываем, что модель — это данные пользователя, а не структура данных.
5 причин, почему вы должны забыть о Redux в приложениях на React
MobX позволяет писать более чистый и понятный код
Давайте сраним 2 фрагмента кода, которые делают тоже самое. Вот как выглядит редюсер в Redux:
Чтобы изменить состояние, вам нужно вызвать функцию, которая называется action в терминологии Редакс:
И в большинстве случаев (не всегда, но это «лучшие практики» которые используются на многих проектах) вам надо будет написать вот такой boilerplate:
Потом надо будет инициализировать store (это надо будет сделать один раз, но всё же):
И прокинуть наш заинициализированный стор дальше в приложение через провайдер (тоже одноразовая операция):
Теперь можно выполнять какие-то операции с данными в ваших компонентах:
Получается, что в случае с Redux, чтобы поменять данные в вашем хранилище, вы должны вызывать какие-то функции, которые будут создавать новый объект состояния… Лично по мне, это звучит как полная ерунда. Давайте глянем на тот же фунционал в исполнении MobX. Наш стор:
И дальше можно использовать в компоненте:
Да, всё верно, вместо каких-то функций, которые изменяют объекты, вы можете использовать классический ООП подход, с классами, их свойствами и методами. Пусть вас не пугают декораторы(@) внутри, они просто добавляют функционал, необходимый для отслеживания изменения данных. Кстати, похожий подход, с классами, для хранения данных используется в Angularjs (Скрин взят отсюда angular.io/start/data):
MobX позволяет писать меньше кода
Чтобы убедиться в этом просто посмотрите на примеры выше. И теперь, вместо написания бесконечного бойлерплейта, можно наконец-то сосредоточиться на написании бизнес логики приложения, что не может не радовать.
Третье — оптимизация производительности
Если посмотреть примеры выше, то можно увидеть, что в случае с MobX я не использовал pure component и это не ошибка. Вам просто не надо использовать никакую оптимизацию в этом случае, потому что ваш компонент будет перерендериваться только тогда, когда данные, которые вы в нем используете поменяются. И да, можно забыть о Pure Components, shouldComponentUpdate и что вы там ещё используете в этих случаях. В идеале, каждый ваш компонент, который не HOC и использует какие то данные из хранилища должен быть observable и тогда вы забудете о проблемах с оптимизацией навсегда.
Четвертое — меньше зависимостей
Тот кто использует Redux, должен не по наслышке знать, что в комплекте с ним идет множество «замечательных» билиотек. И хорошо, если это будет просто thunk, а может быть и так, разработчики пойдут по пути света тьмы и захотят использовать Redux Saga, Reslect и еще кучу непонятных библиотек, которые делают ваш код не только более медленным, но и более сложным в понимании. И допилить какой-то незначительный функционал или найти баг в этом произведении будет невероятно сложно и долго. MobX это ultimate решение == не требующее дополнительных библиотек, лишит вас всех этих прелестей, поэтому с ним бизнес логика вашего приложения будет чистой, как слеза младенца.
Пятая причина — возможность отказаться от setState
setState несёт в себе ряд недостатков (краткий перевод статьи которую можно в оригинале прочитать тут):
1. Он асинхронный.
Это может привести к неожидаемому поведению:
На скрине выше в алерте должно было быть 2, но так как setState асинхронный, он приходит позже.
2. setState ведет к ненужным перерендерам компонента:
а. Он перерендеривается, даже если новое значение == старому значению
б. Есть ситуации, когда изменение state не приведет ни к какому изменению, например, когда у нас есть условия для отбражения в котором стоит state. На скрине ниже при клике произошел перерендер, хотя данные не должны рендериться из-за условия fasle:
в. Иногда данные, которые обновляет setState вообще не играют роли в отрисовке DOM (например, таймеры). И всё равно происходит перерендер компонента.
3. setState подходит далеко не для всех случаев.
Есть компоненты, в которых используются хуки / методы жизенных циклов компонента и в этом случае будет не только происходить лишний перерендер, но эти события (хуки) будут вызываться каждый раз при этом, что может привести к странному поведению.
Использование MobX оградит вас от этих недостатков, ведь можно полностью отказаться от setState:
Когда, зачем и почему может быть полезным Redux
Фреймворков для веб-разработчиков много с разным функционалом, разного размера, для разных целей. Некоторые мастера предпочитают что-то одно, а другие – пробуют новое и ищут нечто интересное. Но почему же Redux остается популярным и востребованным? Что его отличает и для каких целей он подходит? Об этом в материале ниже.
Различных фреймворков много, благодаря чему перед разработчиками и верстальщиками рано или поздно встает вопрос: что лучше использовать в данном проекте, а что – нет, зачем может понадобиться именно та среда разработки, а не эта и так далее. Разумеется, что ответить на эти вопросы можно по-разному, информации об этом тоже множество. Но попробуем в этом материале разобраться в необходимости использования Redux, в причинах его востребованности и его особенностях.
Некоторые его любят, некоторые – уже не сильно, но сколько мастеров – столько и мнений. Управлять огромным потоком данных и их связями действительно было сложновато до появления фреймворка Redux. Но вдохновленный набором шаблонов программирования Flux Facebook, Redux предназначен для управления состоянием данных в приложениях JavaScript. Хотя он в основном используется с библиотекой React, многие веб-разработчики с успехом применяют его с иными фреймворками и библиотеками, такими как jQuery, Angular или Vue.
При очень небольшом размере (около 2 КБ, включая расширения) Redux гарантирует, что каждый компонент некоторого приложения может иметь прямой доступ к состоянию приложения без необходимости отправлять props (входные параметры) дочерним компонентам или использовать функции обратного вызова для отправки данных обратно.
В этом материале давайте посмотрим на то, как Redux глубоко укоренился в концепциях функционального программирования и каким образом можно решить, нужно ли веб-мастеру его использовать в своем приложении, описания интерфейса сайта.
Когда и зачем нужен Redux
Здравый смысл подсказывает, что нет смысла при каждом новом проекте постоянно запускать новые фреймворки и работать только в них, ведь их описывают как самые новые и блестящие инструменты для самых разных задач. Но разве компоненты не имеют своего состояния? Зачем вообще нужен этот вот самый инструмент для управления данным состоянием некоторого компонента?
Не поймите превратно, React велик и могуч и вполне можно в проекте обойтись только одним этим фреймворком и более ничего не использовать. Тем более, что мы уже рассматривали подробно React и приводили примеры веб-проектов, что использовали только эту библиотеку для создания функционала интерфейса (то же самое приложение, по сути). Но по мере того, как приложение становится более сложным, с большим количеством разных компонентов, использование всего лишь одного фреймворка для управления всем этим «массивом», объемом данных и так далее может стать очень проблематичным и осложненным действом. Проблем может появиться много, даже неудобств и излишней трудоёмкости.
И именно в этот момент Redux способен сэкономить время; он значительно уменьшает и упрощает сложности, возникающие в таких больших приложениях. Если у веб-разработчика есть опыт работы в React, он может великолепно понять, что поток данных React таков, что родительские компоненты передают props (входные параметры) дочерним компонентам. В огромном приложении с данными, что используются в разных компонентах, постоянно изменяемыми и сохраняемыми в хранилище, создающими множественные связи – рано или поздно сам код станет очень трудно читать и даже улучшать. Вам самим, в первую очередь.
Чтобы представлять, о чем идет речь, посмотрим на диаграмму ниже.
В React (как, впрочем, и в других фреймворках) связь между двумя компонентами, не имеющими отношения родитель-потомок (дочерний элемент), не рекомендуется. React обращает внимание, что если такое сделать (создать связь), можно вполне создать собственную глобальную систему событий по шаблону Flux; и именно в этот момент и появляется на сцене Redux.
С Redux у нас есть хранилище, в котором можно сохранять все состояния приложения. Если в компоненте A происходит изменение состояния, оно затем передается в хранилище, а другие компоненты B и C, которые должны знать об этом изменении состояния в компоненте A, могут получать эту самую информацию об этом изменении из хранилища:
Увидели? Это даже намного лучше, чем мы предполагали. Если бы наши компоненты взаимодействовали друг с другом, мы создали бы уязвимую и нечитаемую базу программного кода с множеством ошибок. Redux делает ситуацию другой, меняет её и совершенствует.
Компонент A отправляет изменения своего состояния в хранилище, и если Компонент B и C нуждаются в данных об этих изменениях состояния, они могут получить их из хранилища. Таким образом, логика потока данных является бесшовной.
Помимо своей основной миссии, Redux предоставляет и множество иных преимуществ при своем использовании. Посмотрим на основные три таких момента, что являются сами по себе особо важными среди прочих:
Имея только один источник данных (хранилище), у разработчиков становится мало проблем с синхронизацией текущего состояния компонентов (данных этого самого хранилища) с действиями и другими частями приложения.
Redux имеет строгие рекомендации о том, как должен быть организован код. Соответственно и, что разумно, это дополнительно обеспечивает предсказуемый результат, который упрощает управление кодом.
Работа с кодом в Redux включает в себя чистые функции, которые изолированы друг от друга, что коррелирует с золотым правилом написания тестируемого кода: написать небольшие функции, которые делают только что-то одно и являются независимыми.
Здорово и все просто. Если приложение сложное – используем Redux и забываем обо всем прочем. Но так ли это в действительности? Что если существуют некоторые особенности, когда Redux все же нужен?
Когда Redux может не потребоваться
Это может показаться некоторым читателям вполне очевидным, но мы все равно упомянем об этом. Не обязательно использовать Redux. Иногда имеет смысл и вовсе не делать этого. Если какой-либо из сценариев ниже верен для вас, вам, вероятно, вообще не нужен Redux:
Нашли что-то свое, тогда с большой вероятностью Redux может не потребоваться. И неважно, какое приложение, какая работа сайта и какой проект. Все зависит от их сложности, масштабности. Но что касается самого Redux, то этот фреймворк при своем весе около 2 КБ имеет весьма непростые возможности.
Redux в частях и под лупой
Действия (actions)
Это просто события, созданные с помощью функций для отправки данных из приложения в хранилище. Данные могут быть отправлены различными способами, такими как отправка формы, вызов API или обычного взаимодействия с пользователем. Каждое действие в Redux имеет свойство type, которое описывает тип действия, а также «важную» информацию, отправляемую в хранилище. Давайте рассмотрим самый простой пример действия (actions.js) в работе, размещенного на GitHub.
Чтобы вызвать действие в любом месте приложения, Redux использует метод dispatch(), который отправляет действия в хранилище Redux, указывающие на изменение состояния (dispatch.js)
Редюсеры (Reducer)
Редюсеры (Reducer) – это функции, которые считывают из хранилища текущее состояние приложения через отправленное действие, а затем возвращают новое состояние. Посмотрим на код ниже (handle-auth.js), который получает данные о текущем состоянии, а затем возвращает следующее состояние:
При создании более сложных приложений рекомендуется использовать метод combineReducers(). Этот метод объединяет все редюсеры в приложении в один список функций (index-reducer.js), где каждый из них обрабатывает свою часть состояния приложения, а параметр состояния отличается и является персональным для каждой функции.
Здесь также стоит отметить, что редюсеры должны быть написаны с чистыми функциями, особенности которых в том, что:
Хранилище
Хранилище похоже на сердце фреймворка Redux. Это единственный источник истины, в котором находятся все состояния приложения и который обеспечивает доступ к состоянию с помощью нескольких методов, действий отправки данных и регистрации записей. Любое отправленное действие возвращает новое состояние данных в хранилище с помощью редюсеров. И вот как выглядит код хранилища (create-store.js)
Функциональное программирование и Redux
Если вы уже определились и решили использовать Redux в своей работе, кроме всего вышесказанного необходимо знать, как работает функциональное программирование. Redux был основан на принципах функционального программирования и понимание его концепций даст яркое и четкое представление о том, как Redux работает в целом, и почему он способен делать именно то, что делает. Без понимания целостности фреймворка работать в нем сложно и относится такая мысль ко всем средам разработки без исключения.
Так что же это за принципы такие «функционального программирования»?
Функциональное программирование включает в себя написание более простых, меньших и изолированных функций. Следуя этой схеме работа с кодом, тестирование и отладка упрощаются. Поскольку функции малы и изолированы, это делает их многоразовыми в использовании. Вот и поэтому их можно копировать и вставлять в любое место, туда, где они необходимы.
Это также позволяет избежать ситуаций, когда необходимо писать больше кода. Но опять же, функциональное программирование требует понимания понятий, таких как чистые функции, анонимные функции, закрытие и функции первого класса. И это только часть нужных понятий.
Завершение
Это правда. Redux является большой библиотекой по управлению состоянием приложения. И так же, правда и то, что свою популярность фреймворк заслужил. Но что особенно может быть интересным, что Redux успешно применяется в таких проектах, как WordPress, аналогично тому, как RedBox нашел применение в Uber и Twitter. И еще одна правда заключается в том, что Redux не слишком-то подходит для каждого конкретного приложения.
Приложения, выполняющие, в основном, простые действия и не требующие рендеринга (обработки) на стороне сервера, вероятно, не нуждаются в Redux; их действия можно обрабатывать на уровне компонентов. Но в любом случае, Redux – отличный инструмент, который стоит попробовать тем, кому нравится React; если уже знакомы с React и умеете в нем работать.
Впрочем, как и всегда, некоторые полагают Redux устаревшим для работы с данными. Но тут уж, кому и что ближе, а факты – они просто есть.
Смогут ли React-хуки заменить Redux?
Вкратце: хуки хороши, но Redux они не заменят
«Мандаринка» — снимок Малкольма Карлоу (CC-BY-2.0)
Как только API React-хуков вышел, стало появляться много вопросов о том, сможет ли он заменить Redux.
Как по мне, хуки довольно слабо пересекаются с Redux. Они не дают никакого нового волшебства для состояний, а лишь улучшают API для того, что уже было в React. Но с API хуков пользоваться нативным React-инструментарием для состояния стало гораздо удобнее, а поскольку он – еще и более простая замена для классовой модели, мне теперь гораздо чаще удается к месту использовать состояние компонента
Чтобы мои слова стали понятнее, давайте сначала разберемся, зачем вообще нам бывает нужен Redux.
Что такое Redux?
Redux – библиотека и архитектура для предсказуемого управления состоянием, которая легко интегрируется с React.
Вот основные плюсы Redux:
Другими словами, Redux дает вам сверхспособности по организации кода и отладке. С ним гораздо проще писать понятный код и отслеживать причины любого нештатного поведения.
Что такое React-хуки?
С React-хуками можно использовать возможности жизненных циклов React без классов и соответствующих методов жизненных циклов React-компонентов. Они появились в React 16.8.
Вот основные плюсы React-хуков:
Заметьте, что эти фантастические преимущества на самом деле не перекрываются с преимуществами Redux. Можно и нужно использовать React-хуки, чтобы любое изменение состояния было детерминированным, но это всегда было возможностью React, и детерминированная модель состояния Redux замечательно в нее вписывается. Именно так React обеспечивает детерминированный рендеринг представления, и во многом буквально ради этого React и создавался.
С инструментами вроде API хуков react-redux и React-хуком useReducer не нужно выбирать что-то одно. Используйте оба. Используйте и то, и другое, вместе и в сочетании.
Что заменяют хуки?
С появлением API хуков я больше не использую:
Что хуки не заменяют?
Я по-прежнему часто использую:
Когда использовать хуки
Не для каждого приложения и не для каждого компонента бывает нужен Redux. Если у приложения одно-единственное представление, оно не сохраняет и не загружает состояние, и у него нет асинхронного ввода/вывода, я не вижу особого смысла, чтобы добавлять сложность Redux.
Аналогично, если компонент:
В таком случае может быть весьма уместно использовать встроенную в React модель состояния компонента. Вот где нужны React-хуки. К примеру, следующая форма использует хук useState локального состояния компонента из React.
В подобных случаях и раньше можно было использовать локальное состояние компонента, но до React-хуков у меня бы наверняка возник соблазн засунуть его в Redux и всё равно вытащить состояние из пропсов.
Ради состояния компонента пришлось бы делать компонент классовым, устанавливать начальное состояние через синтаксис экземпляра класса или функцию-конструктор, и т.д. — куча лишней сложности просто ради отказа от Redux. Выручало, что есть готовые инструменты для управления состоянием формы с помощью Redux, поэтому не надо было переживать о том, чтобы временное состояние формы не протекло в мою бизнес-логику.
Поскольку я использовал Redux во всех своих сложных приложениях, выбор был простым: в (почти) любой ситуации юзай Redux!
Теперь выбор по-прежнему простой:
Состояние компонента – для состояния отдельных компонентов, Redux – для состояния всего приложения.
Когда использовать Redux
Еще один частый вопрос: «Нужно ли всё класть в Redux? Не сломается ли без этого отладка с помощью путешествия во времени?»
Нет, поскольку в приложении много временных и слишком мелких изменений состояния, которыми нет смысла загромождать логи или отладку с помощью путешествия во времени. Если вы не делаете систему коллективного редактирования в реальном времени, то вам скорее всего и не нужно класть каждое нажатие клавиш пользователя или движение мыши в состояние Redux. Добавляя что-то в состояние Redux, вы добавляете ещё один слой абстракции и усложняете приложение.
Другими словами, не бойтесь использовать Redux, но только когда для этого есть основания.
Redux полезен, если ваш компонент:
Этот компонент не обрабатывает никакой DOM. Это презентационный компонент. Он подключается к Redux с помощью API хуков React-Redux.
Он использует Redux, поскольку данные из этой формы используются в других частях UI, и нам понадобится сохранить данные в базу, как только процедура покупки закончится.
Состояние, за которое он отвечает, используется несколькими компонентами, а не локализовано в одном, оно постоянно, а не временно, и потенциально охватывает несколько страниц или сессий. Для всего этого локальное состояние компонента не подходит, если только не построить свою библиотеку для хранения состояния поверх React API — и это намного сложнее, чем просто использовать Redux.
В будущем API задержки (Suspense) в React сможет помочь с сохранением и загрузкой состояния. Подождем широкой поддержки API Suspense, посмотрим, сможет ли он заменить паттерны сохранения/загрузки в Redux. С Redux можно аккуратно отделять побочные эффекты от остальной логики компонента без имитации сервисов ввода-вывода. (Изоляция эффектов — вот почему я предпочитаю redux-saga вместо thunks). Чтобы на равных конкурировать с такими задачами в Redux, API React нужна возможность изоляции API эффектов.
Redux — это архитектура
Redux — гораздо больше (а часто гораздо меньше), чем библиотека для управления состоянием. Он ещё по сути и подмножество архитектуры Flux, у которой более специфический подход к тому, как вносить изменения в состояние. У меня есть ещё статья, в которой я детально описываю архитектуру Redux.
Я часто использую редьюсеры в стиле Redux, когда требуется сложное состояние компонента, но мне не нужна библиотека Redux. И я использую объекты action в стиле Redux (и даже инструменты Redux вроде Autodux и redux-saga), чтобы отправлять действия в приложениях на Node, вообще не импортируя сам Redux.
Redux всегда был больше архитектурой и нестрогим соглашением, чем библиотекой. Фактически, базовую функциональность Redux можно реализовать самому всего парой десятков строчек кода.
Это всё здорово, если вы захотите больше использовать локальное состояние компонентов с помощью API хуков, а не хвататься чуть что за Redux.
Если потом понадобится сделать состояние постоянным или разделить его с другими компонентами, то 90% уже сделано. Всё что осталось — подключить компонент и добавить редьюсер к вашему хранилищу Redux.
Ещё вопросы и ответы
«Не сломается ли детерминизм, если не класть всё в Redux?»
Нет. По факту, Redux тоже не навязывает детерминизм. Это делает соглашение. Хотите, чтобы состояние в Redux было детерминированным, используйте чистые функции. И чтобы временное состояние компонента было детерминированным, тоже используйте чистые функции.
«Разве нам не нужен Redux как единственный источник правды?»
Принцип единственного источника правды не требует хранить состояние в одном месте. Это лишь означает, что для каждого кусочка состояния должен быть единственный источник правды для этого конкретного кусочка. Может быть множество разных кусочков состояния, у каждого из которых есть свой единственный источник правды.
Это значит, что можно выбрать, что хранить в Redux, а что в состоянии компонента. Можно также получать состояние из других источников вроде браузерного API для текущего адреса страницы.
Redux — отличный способ поддерживать единственный источник правды для состояния приложения, но, если состояние компонента находится в одном компоненте и используется только в одном месте, по определению, у него уже есть единственный источник правы для этого состояния: состояние React-компонента.
Всё, что вы кладёте в Redux-состояние, должно всегда из него же и читаться. Для любого состояния в Redux единственным источником правды должен быть Redux.
Нормально класть всё в Redux, если нужно. Могут быть вопросы с производительностью, если состояние должно часто обновляться, или если в компонентах активно используется зависимое состояние. Не стоит заниматься оптимизацией преждевременно, но если уж взялись за нее, то попробуйте и с Redux, и без него, и посмотрите, есть ли разница. Профилируйте, и помните о модели производительности RAIL.
«Что лучше использовать, функцию connect() из пакета react-redux или API хуков?»
Теперь, если у вас есть куча админских представлений, которым всем нужны права админа, можете создать компонент высшего порядка, который объединит в себе и проверку прав для них всех, и все прочие сквозные задачи, через композицию.
Чтобы использовать это:
Другими словами, на мой взгляд, API функции connect решает задачу компактным кодом, но это далеко не самый понятный и удобный код. Если мне не надо подключать таким же образом другие компоненты, я предпочитаю несравненно более читабельный API хуков, даже при том, что приходится чуть больше печатать.
«Если синглтон — антипаттерн, а Redux — синглтон, то не антипаттерн ли Redux?»
Нет. Синглтон — «запашок» кода, который может указывать на общее изменяемое состояние — вот оно-то действительно антипаттерн. Redux предотвращает общее изменяемое состояние с помощью инкапсуляции (вам не следует мутировать состояние приложения вне редьюсеров, обработку обновления состояния берёт на себя Redux) и передачи сообщений (только отправленные объекты action могут вызывать обновления состояния).
Следующие шаги
Изучите намного больше про React и Redux на EricElliottJS.com. Такие функциональные паттерны, как композиция функции и частичное применение, которые встречались в примерах кода в этой статье, подробно обсуждаются с множеством примеров и видеоуроков.
Изучайте юнит-тестирование React-компонентов, и раз уж зашла речь о тестировании, почитайте про разработку через тестирование (TDD) на TDDDay.com.
Эрик Эллиотт — автор книг «Композиция программного обеспечения» и «Программирование JavaScript-приложений». Как сооснователь EricElliottJS.com и DevAnywhere.io он обучает разработчиков необходимым навыкам разработки программного обеспечения. А также формирует и консультирует команды разработчиков для крипто-проектов, и он участвовал в разработке программ для Adobe Systems, Zumba Fitness, The Wall Street Journal, ESPN, BBC, и лучших артистов, включая Usher, Frank Ocean, Metallica, и многих других.
Он ведет удаленный образ жизни с самой красивой женщиной в мире.
P.S. Это тоже может быть интересно:
Если вам понравилась статья, поделитесь ей!