Продажа квадроциклов, снегоходов и мототехники
second logo
Пн-Чт: 10:00-20:00
Пт-Сб: 10:00-19:00 Вс: выходной

+7 (812) 924 3 942

+7 (911) 924 3 942

Содержание

Редукторы | SEW-EURODRIVE

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

Что такое редуктор?

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

Как работает редуктор?

В зависимости от конструкции, типоразмера и числа ступеней редуктор понижает или повышает частоту вращения двигателя. Получаемое при этом передаточное число i (отношение частоты вращения входного и выходного валов) является одним из важных параметров редуктора. Насколько мощным является редуктор и какие нагрузки он может перемещать, зависит от максимального вращающего момента, измеряемого в ньютон-метрах [Нм].

Какие типы редукторов существуют?

Редукторы различаются по способу передачи усилия; и отсюда получается три основных варианта конструкции: редуктор с параллельными валами, угловой редуктор и планетарный редуктор.

В редукторах с параллельными валами и планетарных редукторах ведущий и ведомый валы расположены в одном направлении (в одной плоскости). Поэтому усилие передается прямолинейно. По компоновке редукторы с параллельными валами бывают цилиндрическими или плоскими цилиндрическими.

Особую форму представляют собой планетарные редукторы. В них передача усилия осуществляется соосно. При этом частота вращения и вращающий момент входного вала – центральной солнечной шестерни – через три или более сателлита передаются на наружную коронную шестерню (сторона выхода) и преобразуются. Особенность: Входной и выходной валы вращаются в одном направлении. В комбинации с серводвигателем планетарные мотор-редукторы для сервопривода обеспечивают очень высокую динамику и точность.

В отличие от этого в угловых редукторах входной и выходной валы расположены перпендикулярно друг другу – как следствие, направление передачи усилия меняется под прямым углом. По конструкции различают три типа угловых редукторов. К ним относятся

конический редуктор, червячный редуктор и, эксклюзивно от SEW-EURODRIVE, угловой редуктор SPIROPLAN®.

Наше предложение: Для любого применения подходящий редуктор из модульной системы

С ассортиментом из всех стандартных типов редукторов и множеством типоразмеров компания SEW-EURODRIVE дает вам доступ к обширной модульной системе редукторов. В сочетании с нашей модульной системой двигателей и дополнительными компонентами получаются миллионы возможных комбинаций. То есть почти для всех возможных случаев применения вы найдете идеально соответствующий вашим требованиям мотор-редуктор – и совсем не важно, какой редуктор вы выбираете: один из наших стандартных, для сервопривода, из нержавеющей стали или взрывозащищенный.

Стандартные редукторы

Стандартные редукторы

Вам нужны прочные и надежные редукторы своего производства и логистики? Тогда наши стандартные редукторы будут верным решением. Выбирайте между разными типами редуктора с множеством типоразмеров и максимальным вращающим моментом до 50 000 Нм. На выбор предлагаются:

Редукторы для сервопривода

Ваша приводная система должна обладать мощной динамикой и высокой точностью? Тогда лучшим выбором будут наши редукторы для сервопривода: И в этом случае с помощью нашей модульной системы вы сможете комбинировать редукторы и двигатели SEW, чтобы получить идеально подходящую вам конфигурацию мотор-редуктора для сервопривода. Наше предложение:

Редукторы из нержавеющей стали

Редукторы из нержавеющей стали

В гигиенических зонах пищевой промышленности с высокими требованиями к чистоте редукторы часто контактируют с агрессивными кислотами и щелочами. Наши редукторы из нержавеющей стали прочны, долговечны, просты в обслуживании

и специально подготовлены к таким условиям применения. Высококачественные корпуса из нержавеющей стали с оптимизированной для очистки поверхностью делают эти редукторы стойкими к воздействию химикатов и загрязнению.

Взрывозащищенные редукторы

Если установки и машины согласно производственным условиям работают в среде с воздушно-газовыми или воздушно-пылевыми смесями, в любой стране существующая угроза взрыва требует строжайшего соблюдения правил взрывобезопасности. Они, конечно, распространяются и на соответствующую приводную технику. По этой причине большинство наших стандартных и сервоприводных редукторов мы предлагаем и во взрывозащищенном исполнении – в соответствии с основными нормативами и стандартами для мирового рынка, от ATEX и IECEx до HazLoc-NA®.

Мотор-редукторы, редукторы, электродвигатели Bonfiglioli - от официального представителя в РФ и СНГ

 

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

 

Наиболее популярные в промышленности червячные мотор-редукторы представлены сериями VF W и W VF ЕР. Крутящий момент этих редукторов составляет до 9200Нм, передаточное отношение – до 32000. Bonfiglioli производит одноступенчатые, двуступенчатые и цилиндро-червячные приводы. Еще одной отличительной особенностью червячных мотор-редукторов Bonfiglioli является возможность исполнения привода в комплектации EP с защитой от коррозии. Такая комплектация отлично подходит для пищевой, химической и фармацевтической отрасли.

 

Цилиндрические мотор-редукторы серии А – еще один практически универсальный вариант для промышленных предприятий. КПД этих редукторов выше, чем у червячных агрегатов и при этом они более компактны. Большой выбор комплектаций и опций редукторов позволяет устанавливать их в самое разнообразное оборудование. Крутящий момент редукторов серии А составляет до 14000 Нм, передаточное отношение до 400.

 

Также обратите внимание на соосные цилиндрические редукторы серии С. Эти редукторы обладают крутящим моментом до 12000Нм, большим диапазоном скоростей и, что немаловажно, демонстрируют отличное соотношение цены и качества.

 

Планетарные редукторы серии 300 обладают высоким перегрузочным коэффициентом. Возможны различные конфигурации выходного вала и расположения двигателя относительно корпуса редуктора. Крутящий момент этих редукторов составляет до 540000 Нм.

 

Как выбрать редуктор?

 

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

 

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

 

Далее необходимо выбрать тип привода. Существует большое количество типов мотор-редукторов, каждый из которых обладает рядом преимуществ. На этом этапе необходимо определить, какой из параметров (мощность, эффективность, крутящий момент, срок службы, уровень шума и т.

д.) является наиболее значимым для выбранного применения. Для этого Вы можете воспользоваться нашим сервисом по подбору редуктора. Скорее всего, уже сейчас становится очевидным, какая модель редуктора соответствует требуемым показателям крутящего момента и передаточных чисел.

 

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

 

Компания Bonfiglioli предлагает до 12 моделей в рамках серии редукторов, чтобы заказчику не приходилось выбирать между компактными габаритами изделия и коэффициентом запаса по передаваемому моменту. Также возможно заказать мотор-редуктор любой модели в компактном исполнении. Технические характеристики (мощность, момент и передаточные числа) компактного мотор-редуктора такие же, как у полноразмерной модели, а вес и габариты могут быть на 10-15% меньше.

 

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

 

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

 

 

Редукторы и мотор-редукторы. Москва, Санкт-Петербург, Владивосток, Россия. PRST.ru

Заменим SITI, Bonfiglioli, Motovario, STM, Varvel, SEW, LENZE, NORD и пр.


на редукторы INNOVARI.

Звоните для консультации:
Москва: +7 (495) 785-75-53.
Санкт-Петербург: +7 (812) 702-65-90, 412-81-23.


Компания «Промситех» представляет Вашему вниманию мотор-редукторы INNOVARI — оптимальное итальянское решение для российских условий.

Основные преимущества:

  • Наличие на складе червячных и цилиндрических мотор-редукторов.
  • Запатентованная модульная конструкция мотор-редукторов обеспечивает взаимозаменяемость по посадочным размерам с SITI, Bonfiglioli, Motovario, STM, Varvel, SEW, LENZE, NORD и др.
  • В случае заказа в Италии сроки поставки от 30 до 45 дней (включая цилиндрические и насадные мотор-редукторы).
  • Нестандартные размеры под Ваши требования изготавливаются даже маленькими партиями.

Итальянское качество

Соответствие российским условиям

  • Полный цикл производства редукторов (конструкция, дизайн, сборка) в Италии, г. Виченца.
  • Проверенное европейское качество: 5-ти летний опыт эксплуатации под марками LENZE и LEESON в Европе и США.

По выбору заказчика:

  • работа при температурах от -30°С до +80°С;
  • антикоррозийное покрытие;
  • выходной вал из нержавеющей стали;
  • оцинкованные винты.

Создавая марку INNOVARI, мы исходили из многолетнего опыта взаимодействия с европейскими поставщиками и понимания потребностей российской промышленности.

Мы отобрали только тех поставщиков в Италии, которые хорошо зарекомендовали себя на европейском рынке и проявили готовность искать наилучшие решения для заданных нами условий.

Ключевые особенности марки INNOVARI:

  • Только итальянское производство: от конструкции до сборки.
  • Только высокое качество: подбор поставщиков с большим опытом и надёжной репутацией.
  • Соответствие продукта российским условиям: возможность работы в разном климате, износостойкость.

Мы планируем и дальше расширять спектр продуктов INNOVARI, руководствуясь данными критериями.

Основные применения редукторов и мотор-редукторов:

— конвейеры, транспортеры;
— мешалки;
— насосы;
— дозаторы;
— кормораздатчики;
— экструдеры;
— термотуннели;
— ленточные пилорамы.

Мотор-редукторы INNORED

Мы предлагаем экономичные червячные редукторы INNORED в квадратном корпусе

Червячные редукторы INNORED построены по модульному принципу: на складе в Москве отдельно хранятся базовые модули и комплектующие. Это предполагает поставку со складов в кратчайшие сроки.

Техническое обслуживание не требуется
Редукторы поставляются с синтетическим маслом на весь срок службы и не требуют обслуживания. Работа при температурах корпуса редуктора от -25°C до +80°C. Редукторы типоразмеров 025-150 поставляются залитыми маслом для любой монтажной позиции.

Подробнее...


Задайте вопрос по нашим компонентам и ценам:

Необходимо ваше согласие на обработку персональных данных

Кто в масле катается

Недавно европеец Оскар Ван Девентер напечатал на 3D-принтере редуктор с экстремально высоким передаточным числом — 11373076. В этом механизме изобретатель соединил два планетарных редуктора. При увеличении количества зубцов шестеренок, использованных в механизме, передаточное число можно увеличить и до 1141624705. Чем такой редуктор может быть полезен, Ван Девентер не объяснил, рассказав только, что при его помощи обычной стоматологической бормашиной можно сдвинуть локомотив. Правда, с очень небольшой скоростью. Вдохновившись разработкой европейца мы решили разобраться в основных типах механических редукторов.

Редуктор представляет собой механизм, позволяющий передавать и преобразовывать крутящий момент с одного вала на другой. Если такой механизм преобразует высокую угловую скорость ведущего вала в более низкую ведомого, его называют демультипликатором, а если наоборот — мультипликатором. Впрочем, так сложилось, что термин демультипликатор используется крайне редко, а устройство, понижающее угловую скорость, называют просто редуктором. В зависимости от типа такой механизм может состоять из нескольких типов шестерен, червяков и валов.

Основными характеристиками редукторов являются передаваемая мощность, угловые скорости и количество валов, а также передаточное число. Любые редукторы уменьшают передаваемую мощность за счет потерь на механическую передачу крутящего момента — из-за трения, массивности конструкции, нагрузок на валах. Угловые скорости на ведущем валу и ведомом могут различаться в десятки, сотни и тысяч раз благодаря передаточному числу редуктора.

Передаточным числом называется соотношение количества зубьев шестеренки на ведущем валу к их числу у шестеренки на ведомом. Оно записывается целым или дробным числом и фактически обозначает, сколько именно раз должен провернуться ведущий вал, чтобы ведомый совершил один полный оборот. В случае с редуктором Ван Девентера, ведущий вал необходимо повернуть 11 миллионов 373 тысячи 76 раз. Только тогда ведомый вал совершит один полный оборот.


В целом редукторы позволяют увеличить усилие на ведомом валу, при этом потратив часть мощности на ведущем и уменьшив скорость вращения. Эту особенность используют тогда, когда необходимо работать с большими нагрузками, например, при помощи относительно маломощного мотора приводить в движение большой по массе транспорт. Например, двигатель седельного тягача КамАЗ-65225 мощностью 400 лошадиных сил может через коробку передач (многоступенчатая разновидность редуктора) сдвигать автопоезд полной массой до 75 тонн.

Сегодня редукторы используются во многих отраслях: на автомобилях, в самолетах и вертолетах, в поездах, станках, велосипедах, то есть везде, где нужно передавать вращательный момент с одного агрегата на другой. Механизмы, позволяющие передавать крутящий момент с одного вала на другой, принято делить на пять наиболее распространенных основных классов: цилиндрические, конические, червячные, планетарные и комбинированные. В последних могут сочетаться несколько типов редукторов.

Цилиндрический редуктор

Иллюстрация: Чабанный Александр / edu.ascon.ru

Цилиндрический редуктор представляет собой механизм, в котором ведущий вал и ведомый находятся в параллельных плоскостях. Передача в них осуществляется с большей шестеренки с прямыми или косыми зубцами на меньшую, по своей форме напоминающую цилиндр. Такие редукторы делятся на несколько подтипов: вертикальные (валы находятся друг над другом) и горизонтальные. Цилиндрические редукторы бывают одно-, двух-, трех- и четырехступенчатыми в зависимости от количества шестерен, установленных между ведущим и ведомым валами.


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

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

Конический редуктор

Иллюстрация: Manuel Neuer / grabcad.com

Конический редуктор используется для передачи вращательного момента с ведущего вала на ведомый в случае, если плоскости их осей пересекаются. В них используются конические шестеренки. Такие механизмы имеют меньшую надежность по сравнению с цилиндрическими, но обладают довольно высоким коэффициентом полезного действия, который может достигать 95 процентов. Благодаря конической конструкции шестерен таких редукторов, они могут иметь несколько выходных валов, оси вращения которых, например, можно расположить в виде креста.


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

Как правило диапазон передаточных чисел в конических редукторах составляет от одного до пяти, но углы наклона оси ведомого вала к ведущему могут быть самыми разнообразными. Такие механизмы, как и цилиндрические, чаще всего используются в различных станках, например, сверлильных. Как и цилиндрические, конические редукторы обратимы, то есть вращая их ведомый вал, можно провернуть ведущий. Однако, из-за особенностей своей конструкции, конические редукторы могут иногда заедать.


Червячный редуктор

Иллюстрация: Исаков Сергей / edu.ascon.ru

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


Редукторы с червячной передачей придумали как альтернативу механизмам с обыкновенной зубчатой передачей, например, цилиндрическим. Они обладают гораздо меньшими размерами, но имеют большее передаточное число. Например, при двухзаходном червяке (имеет две параллельных резьбы) и червячном колесе с сотней зубьев передаточное число составит 50. Это означает, что ведущий вал должен будет совершить 50 полных оборотов, чтобы ведомый вал повернулся один раз.

Червячные редукторы имеют очень высокий коэффициент самоторможения. Это означает, что приложив усилие к ведомому валу провернуть ведущий скорее всего не удастся. Кроме того, червячные редукторы имеют относительно невысокий коэффициент полезного действия (от 70 до 92 процентов) и крайне чувствительны к смазке. Их используют для передачи малой мощности в условиях, когда нет достаточного места для размещения цилиндрического или конического редукторов. Чаще всего червячные редукторы используют для привода конвейеров или ворот.

Планетарный редуктор

Иллюстрация: Филимонов Илья / edu.ascon.ru

Планетарный редуктор — это уже более сложное механическое устройство, получившее свое название из-за способа размещения ведущей, передаточных и ведомой шестерен. Механизм состоит из солнечной шестерни, расположенной в центре конструкции, сателлитов (меньших шестеренок) и эпицикла (коронной шестерни), расположенной на периферии. Вращение коронной шестерни осуществляется солнечной через сателлиты. Последние механически соединяются водилом, кольцом со штырями, на которые и крепятся сателлиты.


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

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

Планетарные редукторы коробки переключения передач во втулке заднего колеса велосипеда.

Фотография: Mirco Rohloff / wikipedia.org

Планетарные редукторы сегодня применяются очень широко: они используются в коробках передач, высокоскоростном мощном инструменте (дрелях, циркулярных и цепных пилах), колесах тяжелого транспорта и велосипедах. Например, такие редукторы устанавливаются в колесах троллейбусов и карьерных самосвалов. К слову, примером планетарного редуктора может служить и шарикоподшипник, хотя в качестве непосредственно редуктора он и не используется.

Комбинированный редуктор

Иллюстрация: Евтеев Алексей, Килькинов Александр / edu.ascon.ru

Из названия этого механизма можно понять, что он может сочетать в себе несколько типов передачи вращательного момента. Так, редукор, использующий червячную и цилиндрическую передачи называется червячно-цилиндрическим, а коническую и цилиндрическую — коническо-цилиндрическим. Комбинирование нескольких классов редукторов в одном механизме может производиться для решения нескольких задач: получения нескольких ведомых валов с разными угловыми скоростями, создания компактной конструкции или редуктора с высокими показателями передачи мощности.


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

Василий Сычев

Планетарный редуктор: устройство и принцип работы

Содержание:

Из чего состоит планетарная передача

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

Наиболее популярная разновидность планетарной передачи состоит из следующих элементов:

  • Солнечная шестерня – малое зубчатое колесо с внешними зубьями, располагающееся в центре механизма
  • Коронная шестерня (эпицикл) – большое зубчатое колесо с внутренними зубьями
  • Водило – эта деталь планетарной передачи механически соединяет все сателлиты. Именно на водиле установлены оси вращения сателлитов.
  • Сателлиты – малые зубчатые колёса с внешними зубьями, располагающиеся между солнечной и коронной шестернёй. Сателлиты находятся в одновременном зацеплении и с солнечной и с коронной шестернёй.

Как работает планетарный редуктор

Работа планетарной передачи простейшей конструкции в случае остановленного эпицикла происходит следующим образом. Во вращение приводится солнечная шестерня. Вместе с ней начинают поворачиваться сцепленные с ней сателлиты. По мере того как сателлиты поворачиваются, они перекатываются по солнечной шестерне и по эпициклу. Тем самым они перемещаются вокруг солнечной шестерни, приводя во вращение водило, на котором закреплены оси сателлитов.

Конструкция планетарного механизма позволяет работать не только с остановленным эпициклом, используя в качестве входа солнечную шестерню, а в качестве выхода – водило. Из трёх перечисленных элементов: солнечная шестерня – водило – эпицикл любые два можно использовать как вход или как выход, а оставшийся третий – затормозить. Планетарная передача при таких способах включения всё равно будет работать, изменится лишь передаточное отношение как по величине, так и по знаку. Всего возможно шесть подобных способов включения, но наиболее широко применяется описанный выше: вход – солнечная шестерня, выход – водило, эпицикл – неподвижен. Такое включение имеет самое большое передаточное отношение из всех имеющихся способов.

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

От планетарной передачи к планетарному редуктору

 

На практике планетарная передача используется как основной элемент для построения планетарных редукторов. В состав редуктора помимо самой передачи входят корпус, опорные подшипники, входной и выходной вал (или иные элементы для подключения вала двигателя и вала нагрузки).

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

Варианты планетарного редуктора: отличия друг от друга

Планетарные редукторы имеют большое количество разновидностей, отличающихся друг от друга по самым различным признакам. Отличия могут заключаться в конструктивной схеме – несколько солнечных шестерён, водил или эпициклов, вместо одной солнечной шестерни, одного водила и одного эпицикла в простейшем варианте редуктора. В некоторых вариантах редукторов плоскости вращения различных планетарных колёс могут быть не параллельны друг другу (пространственные планетарные механизмы).

 


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

Количество сателлитов также может изменяться. Обычно используется от трёх (наиболее распространённый вариант) до шести сателлитов (выходные ступени компактных высоконагруженных редукторов). Форма сателлитов также может быть различной – например двухвенцовые зубчатые колёса в планетарных редукторах, построенных по сложным конструктивным схемам или разрезные подпружиненные зубчатые колёса в редукторах с пониженным люфтом.

Отличие планетарного редуктора от других редукторов

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

В стандартных конструкциях планетарных редукторов доступен широкий ассортимент передаточных чисел (например, до шести тысяч в случае планетарных редукторов maxon motor) в отличие, например, от волновых редукторов (от 30 до 160 в стандартных моделях).

Среди планетарных редукторов можно найти модели с самым разным люфтом: от нескольких градусов для моделей стандартного исполнения до особо низколюфтовых редукторов специальной конструкции (например, планетарные редукторы Harmonic Drive). С одной стороны, это позволяет им быть более точными чем распространённые модели рядных редукторов, с другой стороны они не достигают точности волновых редукторов.

Читать дальше:

Ремонт редуктора заднего моста - цена в Москве и Санкт-Петербурге

Редуктор – механизм, передающий и преобразующий крутящий момент, с одной или более механическими передачами. Главной его задачей является увеличение усилия, прикладываемого к рулю. Именно это заставляет колеса транспортного средства поворачиваться в нужную сторону. Поэтому неисправности редуктора приводят к течи, люфту, тугому вращению руля и могут стать причиной опасной ситуации на дороге.

Процедура ремонта в РОЛЬФ

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

Вне зависимости от типа устройства процесс будет проходить по определенной схеме:

  1. Сначала мастер проведет осмотр на предмет течи масла, диагностику на машине на наличие шума (вой или гула) в механизме заднего или переднего моста.
  2. Потом согласует стоимость ремонта с заказчиком.
  3. После обсуждения всех формальностей приступит к ремонту: произведет демонтаж, проверит зазоры и люфты, оценит состояние подшипников и шестерен.
  4. Затем эксперт разберет устройство заднего или переднего моста на запчасти и произведет замену неисправных деталей (подшипников и сальников, шестерен главной пары и блока сателлитов в случае необходимости).
  5. После окончания соберет установку в обратном порядке, смажет элементы.
  6. Перед тем как устанавливать агрегат обратно на машину, специалист монтирует его обратно на спецтехнику, осуществляет комплексную проверку работы техники с установленным отремонтированным аппаратом. В случае выявления отклонений работы от нормы проводит повторную диагностику.
  7. Далее механик вернет агрегат заднего моста или переднего на место в автомобиль и протестирует результат.

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

Специалисты сервисного центра РОЛЬФ, находящегося в Москве, тщательно соблюдают технологию работы. В экстренных случаях компания осуществляет срочный ремонт редукторов. Если у заказчиков возникают вопросы, механики дают бесплатные консультации по всем техническим и эксплуатационным вопросам. Позвоните по номеру телефона и запишитесь на ремонт в удобное время или приезжайте в сервисный центр по указанному адресу.

Как вернуть рабочее состояние редукторам?

Появились подозрения на поломку части автомобиля? Сервисный центр РОЛЬФ специализируется на диагностике и ремонте редукторов мостов. Профессиональные мастера точно отрегулируют преднатяг подшипников пары и пятно контакта согласно стандарту по ремонту. Восстановят работоспособность элемента после поломки любой сложности. Благодаря прозрачности обслуживания владелец машины сможет присутствовать при проведении работ.

Цилиндрические редукторы - преимущества и недостатки

Цилиндрические редукторы представляют одну из самых больших групп редукторов.
Цилиндрические передачи подразделяются на одно-, двух-, трех- и четырехступенчатые. Данная характеристика представлена исходя из оценки фактора количества ступеней. 

Также существует еще одна классификация – по расстоянию, которое измеряется между осями валов – входного и выходного. По такому типу цилиндрические редукторы делятся на соосные и параллельноосные. 

Если рассматривать способы закрепления, то по такой классификации они могут подразделяться на насадные, на фланцах, «на лапах». 

Преимущества

1. Одно из главных преимуществ – это высокий коэффициент полезного действия. Именно благодаря этому данные редукторы являются экономичными в плане энергопотребления. Принято считать, что КПД такого редуктора 98%, если не брать во внимание передаточное отношение. 

2. Сравнительно большая нагрузочная способность. Если для конкретно поставленных целей использовать цилиндрические редукторы, обладающие соответствующим и габаритами, то их пропускаемая мощность очень велика. 

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

4. Низкая рабочая температура, чему содействует один из самых высоких КПД. Ввиду этого совершенно нет масштабных энергетических потерь. Энергия в большинстве своем полностью передается от источника напрямую получателю.

5. Возможность реверса, несмотря на передаточное число, другими словам – полное отсутствие такого явления, как самоторможение. Выходной вал любого цилиндрического редуктора можно свободно вращать без каких-либо усилий. 

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

Недостатки

1. Сравнительно небольшое передаточное число в режиме работы одной ступени. 

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

3. К недостатку работы можно отнести и отсутствие у такового функции обратимости, а именно – самоторможения. 

Области применения

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

Ограничений как таковых по применению нет. Исключение составляют лишь ситуации, когда в какой-то конкретной ситуации целесообразнее применить другой вид. 

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

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

Понимание того, как редукторы используются в Redux

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

Почему мы упоминаем Redux, когда говорим о редукторах? Redux в значительной степени полагается на функции редуктора, которые принимают предыдущее состояние и действие для выполнения следующего состояния.

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

Что мы подразумеваем под «государством»

Изменения состояния основаны на взаимодействии пользователя или даже на чем-то вроде сетевого запроса. Если состояние приложения управляется Redux, изменения происходят внутри функции редуктора - это единственное место, где происходят изменения состояния.Функция редуктора использует начальное состояние приложения и нечто, называемое действием , чтобы определить, как будет выглядеть новое состояние .

Если бы мы были в классе математики, мы могли бы сказать:

  исходное состояние + действие = новое состояние  

С точки зрения фактической функции редуктора это выглядит так:

  const contactReducer = (state = initialState, action) => {
  // Сделай что-нибудь
}  

Откуда мы взяли это начальное состояние и действие? Это то, что мы определяем.

Состояние параметра

Параметр состояния , который передается функции редуктора, должен быть текущим состоянием приложения. В этом случае мы вызываем это initialState , потому что это будет первое (и текущее) состояние, и ничто не будет предшествовать ему.

  contactReducer (initialState, действие)  

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

  const initialState = {
  контакты: []
}  

Это создает наше initialState , которое равно параметру state , который нам нужен для функции редуктора.

Параметр действия

Действие - это объект, содержащий два ключа и их значения. Обновление состояния, которое происходит в редукторе, всегда зависит от значения action.type . В этом сценарии мы демонстрируем, что происходит, когда пользователь пытается создать новый контакт.Итак, давайте определим действие action.type как NEW_CONTACT .

  const action = {
  тип: 'NEW_CONTACT',
  имя: 'Джон Доу',
  место: 'Лагос Нигерия',
  электронная почта: '[электронная почта защищена]'
}  

Обычно имеется значение полезной нагрузки , которое содержит то, что отправляет пользователь, и которое будет использоваться для обновления состояния приложения. Важно отметить, что action.type является обязательным, но action.payload является необязательным.Использование полезной нагрузки привносит уровень структуры в то, как выглядит объект действия.

Обновление состояния

Состояние должно быть неизменным , то есть его нельзя изменять напрямую. Чтобы создать обновленное состояние, мы можем использовать Object.assign или выбрать оператор распространения.

Object.assign
  const contactReducer = (состояние, действие) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    вернуть объект.assign ({}, state, {
      контакты: [
        ... гос. контакты,
        action.payload
      ]
    })
    дефолт:
      состояние возврата
  }
}  

В приведенном выше примере мы использовали Object.assign () , чтобы убедиться, что мы не изменяем значение состояния напрямую. Вместо этого он позволяет нам вернуть новый объект, который заполнен состоянием, которое ему было передано, и полезной нагрузкой, отправленной пользователем.

Использовать Объект .assign () , важно, чтобы первый аргумент был пустым объектом. Передача состояния в качестве первого аргумента приведет к его мутации, чего мы пытаемся избежать, чтобы сохранить последовательность.

Оператор распространения

Альтернативой object.assign () является использование оператора распространения, например:

  const contactReducer = (состояние, действие) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    возвращаться {
        ...государство, контакты:
        [... state.contacts, action.payload]
    }
    дефолт:
      состояние возврата
  }
}  

Это гарантирует, что входящее состояние останется неизменным, когда мы добавим новый элемент внизу.

Работа с оператором switch

Ранее мы отмечали, что происходящее обновление зависит от значения action.type . Оператор switch условно определяет тип обновления, с которым мы имеем дело, в зависимости от значения действия .тип .

Это означает, что типичный редуктор будет выглядеть так:

  const addContact = (состояние, действие) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    возвращаться {
        ... состояние, контакты:
        [. .. state.contacts, action.payload]
    }
    case 'UPDATE_CONTACT':
      возвращаться {
        // Обработка обновления контактов
      }
    case 'DELETE_CONTACT':
      возвращаться {
        // Обработка удаления контакта
      }
    case 'EMPTY_CONTACT_LIST':
      возвращаться {
        // Обработка списка контактов
      }
    дефолт:
      состояние возврата
  }
}  

Важно, чтобы мы возвращали состояние по умолчанию , когда значение action.тип , указанный в объекте действия, не соответствует тому, что у нас есть в редукторе - скажем, если по неизвестной причине действие выглядит так:

  const action = {
  тип: 'UPDATE_USER_AGE',
  полезная нагрузка: {
    возраст: 19
  }
}  

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

Собираем все вместе

Вот простой пример того, как я реализовал функцию редуктора в React.

См. Пример редуктора Pen
от Кингсли Сайласа Чиджиоке (@kinsomicrote)
на CodePen.

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

Хотите попробовать? Вы можете расширить функцию редуктора, чтобы пользователь мог обновлять возраст контакта. Я хотел бы увидеть, что вы придумали, в разделе комментариев!

Понимание роли редукторов в Redux должно дать вам лучшее понимание того, что происходит под капотом. Если вам интересно узнать больше об использовании редукторов в Redux, стоит проверить официальную документацию.

Основы Redux, часть 3: Состояние, действия и редукторы

  • Как определить значения состояния, которые содержат данные вашего приложения
  • Как определить объекты действий, которые описывают, что происходит в вашем приложении
  • Как написать функции редуктора, которые вычисляют обновленные состояние на основе существующего состояния и действий

Введение #

В части 2: Концепции Redux и поток данных мы рассмотрели, как Redux может помочь нам создавать поддерживаемые приложения, предоставляя нам единое центральное место для размещения глобального состояния приложения.Мы также говорили об основных концепциях Redux, таких как диспетчеризация объектов действий и использование функций-редукторов, которые возвращают новые значения состояния.

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

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

Настройка проекта №

Для этого руководства мы создали предварительно настроенный стартовый проект, в котором уже настроен React, есть некоторые стили по умолчанию и есть поддельный REST API, который позволит нам писать фактические запросы API в нашем приложение. Вы будете использовать это как основу для написания фактического кода приложения.

Для начала вы можете открыть и разветвить этот CodeSandbox:

Вы также можете клонировать тот же проект из этого репозитория Github. После клонирования репо вы можете установить инструменты для проекта с npm install и запустить его с npm start .

Если вы хотите увидеть окончательную версию того, что мы собираемся построить, вы можете проверить tutorial-steps ветка или посмотреть окончательную версию в этом CodeSandbox.

Создание нового проекта Redux + React #

После того, как вы закончите это руководство, вы, вероятно, захотите попробовать поработать над своими собственными проектами. Мы рекомендуем использовать шаблоны Redux для Create-React-App как самый быстрый способ создать новый проект Redux + React . Он поставляется с уже настроенными Redux Toolkit и React-Redux с использованием модернизированной версии примера приложения «счетчик», который вы видели в Части 1. Это позволяет вам сразу приступить к написанию фактического кода приложения без необходимости добавлять пакеты Redux и настраивать магазин.

Если вы хотите узнать конкретные подробности о том, как добавить Redux в проект, см. Это объяснение:

Подробное объяснение: Добавление Redux в проект React

Шаблон Redux для CRA поставляется с уже настроенными Redux Toolkit и React-Redux .Если вы настраиваете новый проект с нуля без этого шаблона, выполните следующие действия:

  • Добавьте пакеты @ reduxjs / toolkit и response-redux
  • Создайте хранилище Redux с помощью RTK configureStore API, и передайте хотя бы одну функцию редуктора
  • Импортируйте хранилище Redux в файл точки входа вашего приложения (например, src / index.js )
  • Оберните корневой компонент React с помощью компонента из React-Redux , например:
Изучение исходного проекта #

Этот первоначальный проект основан на стандартном шаблоне проекта Create-React-App с некоторыми изменениями.

Давайте кратко рассмотрим, что содержит исходный проект:

  • / src
    • index. js : файл точки входа для приложения. Он отображает основной компонент .
    • App.js : основной компонент приложения.
    • index.css : стили для всего приложения
    • / api
      • client.js : небольшой клиент запросов AJAX, который позволяет нам делать запросы GET и POST
      • сервер.js : предоставляет поддельный REST API для наших данных. Наше приложение будет получать данные с этих поддельных конечных точек позже.
    • / exampleAddons : содержит некоторые дополнительные надстройки Redux, которые мы будем использовать позже в руководстве, чтобы показать, как все работает

Если вы загрузите приложение сейчас, вы должны увидеть приветственное сообщение, но остальное приложения в противном случае пусто.

Итак, приступим!

Запуск примера приложения Todo #

Нашим примером приложения будет небольшое приложение «todo».Вы, наверное, видели примеры приложений todo раньше - они делают хорошие примеры, потому что они позволяют нам показать, как делать такие вещи, как отслеживание списка элементов, обработка пользовательского ввода и обновление пользовательский интерфейс при изменении этих данных, что происходит в обычном приложении.

Определение требований #

Начнем с определения начальных бизнес-требований для этого приложения:

  • Пользовательский интерфейс должен состоять из трех основных разделов:
    • Поле ввода, позволяющее пользователю вводить текст нового элемента задачи.
    • Список всех существующих задач
    • Раздел нижнего колонтитула, в котором отображается количество незавершенных задач и параметры фильтрации
  • Элементы списка задач должны иметь флажок, который переключает их статус «завершено».Мы также должны иметь возможность добавить цветной тег категории для предопределенного списка цветов и удаление элементов списка дел.
  • Счетчик должен представлять количество активных задач во множественном числе: «0 элементов», «1 элемент», «3 элемента» и т. Д.
  • Должны быть кнопки, чтобы пометить все задачи как выполненные и очистить все завершенные задачи, удалив их.
  • Должно быть два способа фильтрации отображаемых задач в списке:
    • Фильтрация на основе отображения задач «Все», «Активные» и «Завершенные»
    • Фильтрация на основе выбора одного или нескольких цветов и отображение любых задач чей тег соответствует этим цветам

Позже мы добавим еще несколько требований, но этого достаточно для начала.

Конечная цель - это приложение, которое должно выглядеть так:

Проектирование значений состояния #

Один из основных принципов React и Redux - , что ваш пользовательский интерфейс должен основываться на вашем состоянии . Итак, один из подходов к разработке приложения - сначала подумать обо всех состояниях, необходимых для описания того, как приложение работает. Это тоже хорошая идея чтобы попытаться описать свой пользовательский интерфейс с как можно меньшим количеством значений состояния, чтобы было меньше данных, которые вам нужно отслеживать и обновить.

Концептуально это приложение имеет два основных аспекта:

  • Фактический список текущих задач
  • Текущие параметры фильтрации

Нам также необходимо отслеживать данные, которые пользователь вводит в поле " Поле ввода "Добавить Todo", но это менее важно и мы займемся этим позже.

Для каждого элемента задачи нам нужно сохранить несколько частей информации:

  • Текст, введенный пользователем
  • Логический флаг, указывающий, завершено оно или нет
  • Уникальное значение идентификатора
  • Цветовая категория, если выбрана

Наше поведение фильтрации, вероятно, можно описать с помощью некоторых перечислимых значений:

  • Завершенный статус: «Все», «Активно» и «Завершено»
  • Цвета: «Красный», «Желтый», «Зеленый», » Синий »,« Оранжевый »,« Фиолетовый »

Глядя на эти значения, мы также можем сказать, что задачи - это« состояние приложения »(основные данные, с которыми работает приложение), в то время как значения фильтрации - «состояние пользовательского интерфейса» (состояние, описывающее, что приложение делает прямо сейчас). Это может быть полезно подумайте об этих различных категориях, чтобы понять, как используются различные части состояния.

Проектирование структуры состояний #

В Redux, состояние нашего приложения всегда хранится в простых объектах JavaScript и массивах . Это означает, что вы не можете ставить другие вещи в состоянии Redux - никаких экземпляров классов, встроенные типы JS, такие как Map / Set Promise / Date , функции или что-либо еще, что не является простыми данными JS.

Значение корневого состояния Redux почти всегда представляет собой простой объект JS с другими данными, вложенными в него.

Основываясь на этой информации, мы теперь можем описать типы значений, которые нам нужны внутри нашего состояния Redux:

  • Во-первых, нам нужен массив объектов todo item. Каждый элемент должен иметь следующие поля:
    • id : уникальный номер
    • текст : текст, введенный пользователем
    • завершен : логический флаг
    • цвет : дополнительная категория цвета
  • Затем нам нужно описать наши параметры фильтрации.Нам необходимо:
    • Текущее «завершенное» значение фильтра
    • Массив выбранных в данный момент цветовых категорий

Итак, вот как может выглядеть пример состояния нашего приложения:

Важно отметить, что - это нормально иметь другие значения состояния вне Redux! . Этот пример пока достаточно мал, чтобы у нас действительно было все наше состояние в хранилище Redux, но, как мы увидим позже, некоторые данные действительно не нужно хранить в Redux (например, «открыт ли этот раскрывающийся список?» Или "текущее значение формы ввода").

Разработка действий #

Действия - это простые объекты JavaScript, которые имеют поле типа . Как упоминалось ранее, вы можете рассматривать действие как событие, которое описывает что-то, что произошло в приложении .

Точно так же, как мы разработали структуру состояний на основе требований приложения, мы также должны иметь возможность составьте список некоторых действий, описывающих происходящее:

  • Добавить новую запись задачи на основе текста, введенного пользователем
  • Переключить завершенный статус задачи
  • Выбрать цветовую категорию для задачи
  • Удалить задачу
  • Отметить все задачи как завершенные
  • Очистить все завершенные задачи
  • Выбрать другое значение фильтра «завершено»
  • Добавить новый цветной фильтр
  • Удалить цветной фильтр

Обычно мы помещаем любые дополнительные данные, необходимые для опишите, что происходит в акции .поле полезной нагрузки . Это могло быть число, строка или объект с несколькими полями внутри.

Хранилище Redux не заботится о фактическом тексте поля action.type . Однако ваш собственный код будет выглядеть в action. type , чтобы узнать, требуется ли обновление. Кроме того, вы часто будете смотреть на строки типа действия в Redux. DevTools Extension во время отладки, чтобы узнать, что происходит в вашем приложении. Итак, попробуйте выбрать типы действий, которые читабельны и четко описывают, что происходит - вам будет намного легче понять вещи, когда вы посмотрите на них позже!

На основе этого списка вещей, которые могут произойти, мы можем создать список действий, которые будет использовать наше приложение:

  • {type: 'todos / todoAdded', payload: todoText}
  • {type: ' todos / todoToggled ', payload: todoId}
  • {type:' todos / colorSelected, payload: {todoId, color}}
  • {type: 'todos / todoDeleted', payload: todoId}
  • {type: 'todos / allCompleted'}
  • {type: 'todos / completedCleared'}
  • {type: 'filters / statusFilterChanged', payload: filterValue}
  • {type: 'filters / colorFilterChanged ', payload: {color, changeType}}

В этом случае действия в основном содержат по одной дополнительной части данных, поэтому мы можем поместить это непосредственно в действие . поле полезной нагрузки . Мы могли бы разделить поведение цветового фильтра на два действия: одно для «добавлено» и одно для «удалено», но в этом случае мы сделаем это как одно действие с дополнительным полем внутри специально, чтобы показать, что у нас могут быть объекты в качестве полезной нагрузки действия.

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

Написание редукторов #

Теперь, когда мы знаем, как выглядят наша структура состояний и наши действия, пора написать наш первый редуктор.

Редукторы - это функции, которые принимают текущее состояние и действие в качестве аргументов и возвращают результат нового состояния . Другими словами, (состояние, действие) => newState .

Создание корневого редуктора #

Приложение Redux действительно имеет только одну функцию редуктора: функцию «корневого редуктора» , которую вы передадите в createStore позже. Эта одна функция корневого редуктора отвечает за обработку всех отправляемых действий и вычисление того, каким должен быть результат всего нового состояния каждый раз.

Начнем с создания файла reducer.js в папке src вместе с index.js и App.js .

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

Редуктор может быть вызван с undefined в качестве значения состояния при инициализации приложения. Если это произойдет, нам нужно предоставить значение начального состояния, чтобы остальной части кода редуктора было с чем работать. Редукторы обычно используют синтаксис аргумента по умолчанию ES6 для предоставления начального состояния: (state = initialState, action) .

Затем давайте добавим логику для обработки действия todos / todoAdded .

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

Это ... очень много работы, чтобы добавить один элемент todo в состояние.Зачем нужна вся эта дополнительная работа?

Правила редукторов #

Ранее мы говорили, что редукторы должны всегда следовать некоторым особым правилам :

  • Они должны вычислять только новое значение состояния на основе состояния и действия аргументов
  • Они являются не разрешено изменять существующее состояние . Вместо этого они должны сделать неизменяемое обновление , скопировав существующее состояние и внося изменения в скопированные значения.
  • Они не должны выполнять асинхронную логику или другие «побочные эффекты».

«Побочный эффект» - это любое изменение состояния или поведения, которое можно увидеть за пределами возврата значения из функции . Вот некоторые распространенные побочные эффекты:

  • Запись значения в консоль
  • Сохранение файла
  • Установка асинхронного таймера
  • Выполнение HTTP-запроса AJAX
  • Изменение некоторого состояния, существующего вне функции, или изменение аргументов функции
  • Генерация случайных чисел или уникальных случайных идентификаторов (например, Math.random () или Date.now () )

Любая функция, которая следует этим правилам, также известна как «чистая» функция , даже если она специально не написана как функция-редуктор.

Но почему эти правила важны? Есть несколько разных причин:

  • Одна из целей Redux - сделать ваш код предсказуемым. Когда вывод функции рассчитывается только на основе входных аргументов, легче понять, как работает этот код, и протестировать его.
  • С другой стороны, если функция зависит от внешних переменных или ведет себя случайным образом, вы никогда не знаете, что произойдет, когда вы ее запустите.
  • Если функция изменяет другие значения, включая ее аргументы, это может неожиданно изменить способ работы приложения. Это может быть частым источником ошибок, таких как «Я обновил свое состояние, но теперь мой пользовательский интерфейс не обновляется, когда должен!»
  • Некоторые возможности Redux DevTools зависят от того, правильно ли ваши редукторы следуют этим правилам.

Правило о «неизменяемых обновлениях» особенно важно, и о нем стоит поговорить подробнее.

Редукторы и неизменяемые обновления #

Ранее мы говорили о «мутации» (изменение существующих значений объекта / массива) и «неизменности» (обработка значений как чего-то, что нельзя изменить).

В Redux, наши редукторы никогда не позволяют изменять исходные / текущие значения состояния!

Есть несколько причин, по которым вы не должны изменять состояние в Redux:

  • Это вызывает ошибки, такие как некорректное обновление пользовательского интерфейса для отображения последних значений
  • Это затрудняет понимание того, почему и как состояние было изменено. обновлено
  • Это затрудняет написание тестов
  • Это нарушает возможность правильного использования «отладки путешествия во времени»
  • Это идет вразрез с предполагаемым духом и шаблонами использования для Redux

Итак, если мы не можем изменить оригиналы , как вернуть обновленное состояние?

Редукторы могут делать только копию оригинальных значений, а затем они могут изменять копии.

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

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

Однако, если вы думаете, что «написание неизменяемых обновлений вручную таким способом сложно запомнить и сделать правильно»... Да, ты прав! 🙂

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

В реальных приложениях вам не придется вручную писать эти сложные вложенные неизменяемые обновления . В части 8: Современный Redux с Redux Toolkit вы узнайте, как использовать Redux Toolkit для упрощения написания неизменной логики обновления в редукторах.

Обработка дополнительных действий #

Имея это в виду, давайте добавим логику редуктора еще для пары случаев.Во-первых, переключение поля задачи завершено на основе его идентификатора:

И поскольку мы сосредоточились на состоянии задач, давайте добавим случай для обработки действия «видимость выбора изменена»:

У нас есть только обработал 3 действия, но это уже становится немного длинным. Если мы попытаемся обработать каждое действие в этом редукторе функция, будет трудно все это прочитать.

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

Разделение редукторов #

В рамках этого редукторы Redux обычно разделяются на части на основе раздела состояния Redux, в котором они обновляют . В настоящее время состояние нашего приложения todo состоит из двух разделов верхнего уровня: state.todos и state.filters . Итак, мы можем разделить функцию большого корневого редуктора на два меньших редуктора - todosReducer и FiltersReducer .

Итак, где же должны жить эти разделенные функции редуктора?

Мы рекомендуем организовать папки и файлы приложений Redux на основе «функций» - кода, относящегося к определенной концепции. или область вашего приложения. Код Redux для конкретной функции обычно записывается в виде одного файла, известного как "slice" файл , который содержит всю логику редуктора и весь связанный с действием код для этой части состояния вашего приложения.

Из-за этого редуктор для определенного раздела состояния приложения Redux называется «редуктор среза» . Как правило, некоторые из объектов действия будут тесно связаны с конкретным редуктором среза, поэтому строки типа действия должны начинаться с имени этой функции (например, 'todos' ) и описывать произошедшее событие (например, 'todoAdded '), объединенные в одну строку (' todos / todoAdded ').

В нашем проекте создайте новую папку features , а затем папку todos внутри нее. Создайте новый файл с именем todosSlice.js , и давайте вырежем и вставим исходное состояние, связанное с задачей, в этот файл:

src / features / todos / todosSlice.js

Теперь мы можем скопировать логику обновления todos. Однако здесь есть важное отличие. Этот файл должен обновлять только состояние, связанное с задачами - он больше не вложен! Это еще одна причина, по которой мы разделили редукторы.Поскольку состояние задач - это сам по себе массив, нам не нужно копировать сюда внешний объект корневого состояния. Это упрощает чтение этого редуктора.

Это называется составом редуктора , и это фундаментальный образец построения приложений Redux.

Вот как выглядит обновленный редуктор после того, как мы обработаем эти действия:

src / features / todos / todosSlice.js

Это немного короче и легче для чтения.

Теперь мы можем сделать то же самое с логикой видимости. Создайте src / features / filters / filtersSlice.js , и давайте переместим туда весь код, связанный с фильтрами:

src / features / filters / filtersSlice.js

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

Объединение редукторов #

Теперь у нас есть два отдельных файла срезов, каждый со своей собственной функцией редуктора срезов. Но, как мы уже говорили ранее, при создании хранилища Redux требуется одна функция корневого редуктора .Итак, как мы можем вернуться к корневому редуктору, не помещая весь код в одну большую функцию?

Поскольку редукторы являются обычными функциями JS, мы можем импортировать редукторы фрагментов обратно в reducer.js и написать новый корневой редуктор, единственная задача которого - вызывать две другие функции.

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

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

combReducers #

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

В базовую библиотеку Redux входит утилита combReducers , которая выполняет тот же шаблонный шаг за нас.Мы можем заменить наш рукописный rootReducer на более короткий, созданный combReducers .

Теперь, когда нам нужно combReducers , пришло время фактически установить базовую библиотеку Redux :

Как только это будет сделано, мы можем импортировать combReducers и использовать его:

combReducers принимает объект, в котором имена ключей станут ключами в вашем корневом объекте состояния, а Значения - это функции редуктора срезов, которые знают, как обновлять эти срезы состояния Redux.

Помните, имена ключей, которые вы даете combReducers , определяют, какими будут имена ключей вашего объекта состояния!

Что вы узнали #

Состояние, действия и редукторы являются строительными блоками Redux . Каждое приложение Redux имеет значения состояния, создает действия для описания того, что произошло, и использует функции редуктора для вычисления новых значений состояния на основе предыдущего состояния и действия.

Вот содержимое нашего приложения на данный момент:

  • Приложения Redux используют простые объекты JS, массивы и примитивы в качестве значений состояния
    • Значение корневого состояния должно быть простым объектом JS
    • Состояние должно содержать наименьший объем данных, необходимых для работы приложения
    • Классы, обещания, функции и другие непростые значения, если не переходит в состояние Redux
    • Редукторы не должны создавать случайные значения, такие как Math.random () или Date.now ()
    • Это нормально, когда другие значения состояния, которых нет в хранилище Redux (например, состояние локального компонента), бок о бок с Redux
  • Действия представляют собой простые объекты с поле типа , которое описывает, что произошло
    • Поле типа должно быть читаемой строкой и обычно записывается как 'feature / eventName'
    • Действия могут содержать другие значения, которые обычно хранятся в действие.полезная нагрузка поле
    • Действия должны иметь наименьший объем данных, необходимых для описания того, что произошло
  • Редукторы - это функции, которые выглядят как (состояние, действие) => newState
    • Редукторы всегда должны следовать особым правилам:
      • Вычислять новое состояние только на основе состояния и действия Аргументы
      • Никогда не изменять существующее состояние - всегда возвращать копию
      • Нет «побочных эффектов», таких как вызовы AJAX или асинхронная логика
  • Редукторы должны быть разделены, чтобы их было легче читать.
    • Редукторы обычно разделяются на основе ключей состояния верхнего уровня или «фрагментов» состояния
    • Редукторы обычно записываются в файлы «фрагментов», организованные в папки «функций»
    • Редукторы можно комбинировать вместе с Redux combReducers функция
    • Ключевые имена, данные combReducers определяют ключи объекта состояния верхнего уровня

Что дальше? #

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

В части 4: Store мы увидим, как создать хранилище Redux и запустить нашу логику редуктора.

Редукторы | Redux

Содержание #

Редукторы #

Как разделить состояние между двумя редукторами? Должен ли я использовать

combReducers ? #

Предлагаемая структура для хранилища Redux состоит в том, чтобы разделить объект состояния на несколько «фрагментов» или «доменов» по ​​ключу и предоставить отдельную функцию редуктора для управления каждым отдельным фрагментом данных.Это похоже на то, как стандартный шаблон Flux имеет несколько независимых хранилищ, а Redux предоставляет служебную функцию combReducers , чтобы упростить этот шаблон. Однако важно отметить, что combReducers - это , а не - это просто служебная функция для общего случая использования единственной функции-редуктора для каждого фрагмента состояния с простыми объектами JavaScript для данных.

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

  • Если редуктору нужно знать данные из другого среза состояния, может потребоваться реорганизация формы дерева состояний, чтобы один редуктор обрабатывал больше данных.
  • Вам может потребоваться написать несколько пользовательских функций для обработки некоторых из этих действий. Для этого может потребоваться замена combReducers вашей собственной функцией редуктора верхнего уровня. Вы также можете использовать такую ​​утилиту, как reduce-reducer, для запуска combReducers для обработки большинства действий, а также запустить более специализированный reducer для определенных действий, которые пересекают срезы состояний.
  • Промежуточное ПО с асинхронной логикой, например redux-thunk, имеет доступ ко всему состоянию через getState () . Создатель действия может извлекать дополнительные данные из состояния и помещать их в действие, чтобы каждый редуктор имел достаточно информации для обновления своего собственного среза состояния.

В общем, помните, что редукторы - это просто функции: вы можете организовывать их и подразделять как хотите, и вам предлагается разбить их на более мелкие, повторно используемые функции («композиция редукторов»).При этом вы можете передать настраиваемый третий аргумент от родительского редуктора, если дочернему редуктору требуются дополнительные данные для вычисления его следующего состояния. Вам просто нужно убедиться, что вместе они соблюдают основные правила редукторов: (состояние, действие) => newState и постоянно обновляют состояние, а не изменяют его напрямую.

Дополнительная информация #

Документация

Обсуждения

Должен ли я использовать оператор

switch для обработки действий? #

No.Вы можете использовать любой подход, который хотите отреагировать на действие в редьюсере. Оператор switch является наиболее распространенным подходом, но можно использовать операторы if , справочную таблицу функций или создать функцию, которая абстрагирует это. Фактически, хотя Redux действительно требует, чтобы объекты действия содержали поле типа , ваша логика редуктора даже не должна полагаться на это для обработки действия. Тем не менее, стандартный подход определенно использует оператор switch или таблицу поиска на основе типа .

Дополнительная информация #

Документация

Обсуждения

Что такое редуктор в JavaScript / React / Redux?

Концепция Reducer стала популярной в JavaScript с появлением Redux как решения управления состоянием для React. Но не беспокойтесь, вам не нужно изучать Redux, чтобы понимать редукторы. В основном редукторы нужны для управления состоянием в приложении. Например, если пользователь что-то пишет в поле ввода HTML, приложение должно управлять этим состоянием пользовательского интерфейса (например,грамм. контролируемые компоненты).

Давайте углубимся в детали реализации: по сути, редуктор - это функция, которая принимает два аргумента - текущее состояние и действие - и возвращает новое состояние на основе обоих аргументов. В псевдофункции это может быть выражено как:

 
 

(состояние, действие) => newState

Например, в JavaScript для сценария увеличения числа на единицу это будет выглядеть следующим образом:

 
 

функция counterReducer (состояние, действие) {

возврат состояния + 1;

}

Или определенная как стрелочная функция JavaScript, для той же логики она будет выглядеть следующим образом:

 
 

const counterReducer = (state, action) => {

return state + 1;

};

В этом случае текущее состояние является целым числом (например,грамм. count), а функция reducer увеличивает счетчик на единицу. Если мы переименуем аргумент state в count , он может быть более читаемым и доступным для новичков в этой концепции. Однако имейте в виду, что count по-прежнему является состоянием:

 
 

const counterReducer = (count, action) => {

return count + 1;

};

Функция reducer - это чистая функция без каких-либо побочных эффектов, что означает, что при одинаковом вводе (например,грамм. состояние и действие ) ожидаемый результат (например, newState ) всегда будет одинаковым. Это делает функции-редукторы идеальными для анализа изменений состояния и их изолированного тестирования. Вы можете повторить тот же тест с тем же входом, что и аргументы, и всегда ожидать один и тот же результат:

 
 

expect (counterReducer (0)). To.equal (1);

ожидать (counterReducer (0)). To.equal (1);

В этом суть функции редуктора.Однако мы еще не затронули второй аргумент редуктора: действие. Действие обычно определяется как объект со свойством типа . В зависимости от типа действия редуктор может выполнять условные переходы между состояниями:

 
 

const counterReducer = (count, action) => {

if (action.type === 'INCREASE') {

return count +1;

}

if (action.type === 'DECREASE') {

счетчик возврата - 1;

}

счетчик возврата;

};

Если действие типа не соответствует ни одному условию, мы возвращаем неизмененное состояние.Тестирование функции редуктора с несколькими переходами между состояниями - при одном и том же входе она всегда будет возвращать один и тот же ожидаемый результат - все еще остается верным, как упоминалось ранее, что демонстрируется в следующих тестовых примерах:

 
 

expect (counterReducer (0, {тип: 'УВЕЛИЧИТЬ'})). to.equal (1);

ожидать (counterReducer (0, {тип: 'УВЕЛИЧИТЬ'})). To.equal (1);

ожидать (counterReducer (0, {тип: 'УМЕНЬШИТЬ'})). To.equal (-1);

ожидать (counterReducer (0, {type: 'UNMATCHING_ACTION'})).to.equal (0);

Однако более вероятно, что вы увидите оператор switch case в пользу операторов if else, чтобы отобразить несколько переходов между состояниями для функции редуктора. Следующий редуктор выполняет ту же логику, что и раньше, но выражается с помощью оператора switch case:

 
 

const counterReducer = (count, action) => {

switch (action. type) {

case 'INCREASE':

счетчик возврата + 1;

case 'DECREASE':

количество возвратов - 1;

по умолчанию:

счетчик возврата;

}

};

В этом сценарии счетчик сам по себе является состоянием, к которому мы применяем наши изменения состояния путем увеличения или уменьшения счетчика.Однако часто в качестве состояния используется не примитив JavaScript (например, целое число для подсчета), а сложный объект JavaScript. Например, счетчик может быть одним свойством нашего объекта state :

 
 

const counterReducer = (state, action) => {

switch (action.type) {

case 'INCREASE':

return {... состояние, количество: состояние.count + 1};

case 'DECREASE':

return {... состояние, количество: состояние.count - 1};

по умолчанию:

состояние возврата;

}

};

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

  • Состояние, обрабатываемое функцией редуктора, является неизменным. Это означает, что входящее состояние - входящее в качестве аргумента - никогда напрямую не изменяется. Поэтому функция редуктора всегда должна возвращать новый объект состояния.Если вы не слышали о неизменяемости, возможно, вам стоит ознакомиться с темой о неизменяемых структурах данных.

  • Поскольку мы знаем, что состояние является неизменной структурой данных, мы можем использовать оператор распространения JavaScript, чтобы создать новый объект состояния из входящего состояния и часть, которую мы хотим изменить (например, count свойство ). Таким образом мы гарантируем, что другие свойства, которые не касаются входящего объекта состояния, остаются неизменными для нового объекта состояния.

Давайте посмотрим на эти два важных момента в коде на другом примере, где мы хотим изменить фамилию объекта человека с помощью следующей функции редуктора:

 
 

const personReducer = (person, action) => {

switch (action. type) {

case 'INCREASE_AGE':

return {... person, age: person.age + 1};

case 'CHANGE_LASTNAME':

return {... person, lastname: action.lastname};

по умолчанию:

возвращающее лицо;

}

};

В тестовой среде мы могли изменить фамилию пользователя следующим образом:

 
 

const initialState = {

firstname: 'Liesa',

lastname: 'Huppertz',

age: 30 ,

};

const action = {

type: 'CHANGE_LASTNAME',

lastname: 'Wieruch',

};

const result = personReducer (initialState, действие);

ожидать (результат).to.equal ({

имя: 'Liesa',

фамилия: 'Wieruch',

возраст: 30,

});

Вы видели, что с помощью оператора распространения JavaScript в нашей функции редуктора мы используем все свойства из объекта текущего состояния для нового объекта состояния, но переопределяем определенные свойства (например, lastname ) для этого нового объекта. Вот почему вы часто будете видеть оператор распространения для сохранения неизменности операции состояния (= состояние не изменяется напрямую).

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

Часто дополнительные полезные данные действия помещаются в другое общее свойство полезных данных , чтобы сохранить верхний уровень свойств объекта действия более общего (.например, {тип, полезная нагрузка} ). Это полезно, если тип и полезная нагрузка всегда разделяются бок о бок. В нашем предыдущем примере кода действие изменилось бы на следующее:

 
 

const action = {

type: 'CHANGE_LASTNAME',

payload: {

lastname: 'Wieruch',

},

};

Функция редуктора тоже должна измениться, потому что она должна погрузиться на один уровень глубже в действие:

 
 

const personReducer = (person, action) => {

switch (action. type) {

case 'INCREASE_AGE':

return {... person, age: person.age + 1};

case 'CHANGE_LASTNAME':

return {... person, lastname: action.payload.lastname};

по умолчанию:

возвращающее лицо;

}

};

В основном вы узнали все, что вам нужно знать о редукторах. Они используются для выполнения переходов между состояниями от A к B с помощью действий, которые предоставляют дополнительную информацию.Вы можете найти примеры редукторов из этого руководства в этом репозитории GitHub, включая тесты. Здесь снова все вкратце:

  • Синтаксис: По сути функция редуктора выражается как (состояние, действие) => newState .
  • Неизменяемость: Состояние никогда не изменяется напрямую. Вместо этого редуктор всегда создает новое состояние.
  • Переходы состояний: Редуктор может иметь условные переходы состояний.
  • Действие: Обычный объект действия поставляется с обязательным свойством типа и необязательной полезной нагрузкой:
    • Свойство типа выбирает условный переход состояния.
    • Полезные данные действия предоставляют информацию для перехода между состояниями.

Также ознакомьтесь с этим руководством, если вы хотите узнать, как использовать редукторы в React с хуком useReducer.

Array.prototype.reduce () - JavaScript | MDN

Метод reduce () выполняет редуктор функция (которую вы предоставляете) для каждого элемента массива, что приводит к одному выходу ценить.

Исходный код этого интерактивного примера хранится в репозитории GitHub.Если вы хотите внести свой вклад в проект интерактивных примеров, клонируйте https://github.com/mdn/interactive-examples и отправьте нам запрос на перенос.

Функция редуктора принимает четыре аргумента:

  1. Аккумулятор
  2. Текущее значение
  3. Текущий индекс
  4. Исходный массив

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

  arr.reduce (callback (аккумулятор, currentValue, [, index [, array]]) [, initialValue])  

Параметры

callback

Функция, выполняемая для каждого элемента в массиве (кроме первого, если нет предоставляется начальное значение ).

Требуется четыре аргумента:

аккумулятор
Накопитель накапливает возвращаемых значений обратного вызова .Это накопленное значение, ранее возвращенное при последнем вызове обратного вызова, или initialValue , если оно было предоставлено (см. Ниже).
текущее значение
Текущий обрабатываемый элемент в массиве.
индекс Дополнительно
Индекс текущего обрабатываемого элемента в массиве. Начинается с индекса 0 , если указано значение initialValue .В противном случае запускается из индекса 1 .
массив Дополнительно
Был вызван массив reduce () .
начальное значение Необязательно
Значение для использования в качестве первого аргумента при первом вызове обратный звонок . Если нет начальное значение предоставлен, первый элемент в массиве будет использоваться в качестве начального аккумулятор значение и пропущено как текущее значение .Вызов reduce () для пустого массива без initialValue выдаст TypeError .

Возвращаемое значение

Единственное значение, полученное в результате сокращения.

Метод reduce () выполняет обратный вызов один раз для каждое присвоенное значение, присутствующее в массиве, принимает четыре аргумента:

  1. аккумулятор
  2. текущее значение
  3. текущий Индекс
  4. массив

При первом вызове обратного вызова аккумулятор и currentValue может быть одним из двух значений.Если initialValue предоставляется в вызове reduce () , тогда аккумулятор будет равен initialValue и currentValue будет равно первому значению в массиве. Если нет начальное значение при условии, что аккумулятор будет равен первому значению в массив, а currentValue будет равно второму.

Примечание: Если initialValue не указано, reduce () выполнит функцию обратного вызова, начиная с индекса 1 , пропуская первый индекс. Если начальное значение равно при условии, что он начнется с индекса 0 .

Если массив пуст и не указано initialValue , TypeError будет выброшено.

Если в массиве только один элемент (независимо от позиции) и нет initialValue предоставляется, или если initialValue предоставляется, но массив пуст, одиночное значение будет возвращен без вызова обратного вызова .

Почти всегда безопаснее указать начальное значение , потому что может быть до четыре возможных типа выхода без initialValue , как показано в следующем примере:

  let maxCallback = (acc, cur) => Math. max (acc.x, cur.x);
пусть maxCallback2 = (max, cur) => Math.max (max, cur);


[{x: 2}, {x: 22}, {x: 42}] .reduce (maxCallback);
[{x: 2}, {x: 22}].уменьшить (maxCallback);
[{x: 2}] .reduce (maxCallback);
[] .reduce (maxCallback);


[{x: 22}, {x: 42}] .map (el => el.x)
                        .reduce (maxCallback2, -Бесконечность);
  

Как работает reduce ()

Предположим, что произошло следующее использование reduce () :

  [0, 1, 2, 3, 4] .reduce (function (аккумулятор, currentValue, currentIndex, array) {
  вернуть аккумулятор + currentValue
})
  

Обратный вызов будет вызываться четыре раза с аргументами и возвращаемыми значениями в каждом звоните следующим образом:

обратный вызов итерация аккумулятор текущее значение текущий Индекс массив возвращаемое значение
первый звонок 0 1 1 [0, 1, 2, 3, 4] 1
второй звонок 1 2 2 [0, 1, 2, 3, 4] 3
третий звонок 3 3 3 [0, 1, 2, 3, 4] 6
четвертый звонок 6 4 4 [0, 1, 2, 3, 4] 10

Значение, возвращаемое функцией reduce () , будет значением последнего обратного вызова. вызов ( 10 ).

Вы также можете указать функцию стрелки вместо полноценной функции. Приведенный ниже код даст тот же результат, что и код в блок выше:

  [0, 1, 2, 3, 4] .reduce ((аккумулятор, currentValue, currentIndex, array) => аккумулятор + currentValue)
  

Если бы вы указали initialValue в качестве второго аргумента до reduce () , результат будет выглядеть так:

,  [0, 1, 2, 3, 4].reduce ((аккумулятор, currentValue, currentIndex, array) => {
    вернуть аккумулятор + currentValue
}, 10)
  
обратный вызов итерация аккумулятор текущее значение текущий Индекс массив возвращаемое значение
первый звонок 10 0 0 [0, 1, 2, 3, 4] 10
второй звонок 10 1 1 [0, 1, 2, 3, 4] 11
третий звонок 11 2 2 [0, 1, 2, 3, 4] 13
четвертый звонок 13 3 3 [0, 1, 2, 3, 4] 16
пятый звонок 16 4 4 [0, 1, 2, 3, 4] 20

Значение, возвращаемое функцией reduce () , в этом случае будет 20 .

 


if (! Array.prototype.reduce) {
  Object.defineProperty (Array.prototype, 'уменьшить', {
    value: function (callback) {
      if (this === null) {
        throw new TypeError ('Array.prototype.reduce' +
          'вызвано по null или undefined');
      }
      if (typeof callback! == 'функция') {
        выбросить новый TypeError (обратный вызов +
          'не функция');
      }

      
      var o = Object (это);

      
      var len = o.length >>> 0;

      
      var k = 0;
      значение var;

      если (аргументы.length> = 2) {
        значение = аргументы [1];
      } еще {
        while (k  = len) {
          throw new TypeError ('Уменьшение пустого массива' +
            'без начального значения');
        }
        значение = o [k ++];
      }

      
      в то время как (k  

Осторожно: Если вам нужна поддержка действительно устаревших движков JavaScript которые не поддерживают объект .defineProperty () , лучше не использовать полифил Array.prototype методы вообще, так как вы не можете их сделать неперечислимый .

Суммировать все значения массива

  let sum = [0, 1, 2, 3] .reduce (function (аккумулятор, currentValue) {
  вернуть аккумулятор + currentValue
}, 0)


  

Альтернативно записывается стрелкой:

  let total = [0, 1, 2, 3] .reduce (
  (аккумулятор, текущее значение) => аккумулятор + текущее значение,
  0
)  

Сумма значений в массиве объектов

Чтобы суммировать значения, содержащиеся в массиве объектов, вы должны предоставить initialValue , чтобы каждый элемент проходил через вашу функцию.

  пусть initialValue = 0
let sum = [{x: 1}, {x: 2}, {x: 3}]. reduce (function (аккумулятор, currentValue) {
    возвратный аккумулятор + currentValue.x
}, Начальное значение)

console.log (сумма)
  

Альтернативно записывается стрелкой:

  пусть initialValue = 0
let sum = [{x: 1}, {x: 2}, {x: 3}]. reduce (
    (аккумулятор, currentValue) => аккумулятор + currentValue.x
    , Начальное значение
)

console.log (сумма)  

Сглаживание массива массивов

  let flattened = [[0, 1], [2, 3], [4, 5]].уменьшать(
  function (аккумулятор, currentValue) {
    вернуть аккумулятор .concat (currentValue)
  },
  []
)

  

Альтернативно записывается стрелкой:

  let flattened = [[0, 1], [2, 3], [4, 5]]. Reduce (
  (аккумулятор, текущее значение) => аккумулятор.concat (текущее значение),
  []
)
  

Подсчет экземпляров значений в объект

  let names = ['Алиса', 'Боб', 'Тифф', 'Брюс', 'Алиса']

let counttedNames = names.reduce (function (allNames, name) {
  if (имя в allNames) {
    allNames [имя] ++
  }
  еще {
    allNames [имя] = 1
  }
  вернуть allNames
}, {})


  

Группировка объектов по свойствам

  let people = [
  {имя: 'Алиса', возраст: 21},
  {имя: 'Макс', возраст: 20},
  {имя: 'Джейн', возраст: 20}
];

function groupBy (objectArray, property) {
  вернуть objectArray.reduce (function (acc, obj) {
    let key = obj [свойство]
    if (! acc [ключ]) {
      acc [ключ] = []
    }
    acc [ключ] .push (объект)
    возврат в соотв.
  }, {})
}

let groupedPeople = groupBy (люди, 'возраст')








  

Связывание массивов, содержащихся в массиве объектов, с помощью оператора распространения и initialValue

 

пусть друзья = [{
  имя: 'Анна',
  книги: ['Библия', 'Гарри Поттер'],
  возраст: 21
}, {
  имя: 'Боб',
  книги: [«Война и мир», «Ромео и Джульетта»],
  возраст: 26
}, {
  имя: 'Алиса',
  книги: [«Властелин колец», «Сияние»],
  возраст: 18
}]



пусть allbooks = друзья.уменьшить (функция (аккумулятор, текущее значение) {
  return [... аккумулятор, ... currentValue.books]
}, ['Alphabet'])





  

Удалить повторяющиеся элементы в массиве

Примечание: Если вы используете среду, совместимую с Установите и Array.from () , вы можете использовать let ordersArray = Array.from (new Set (myArray)) , чтобы получить массив, в котором повторяющиеся элементы были удалены.

  пусть myArray = ['a', 'b', 'a', 'b', 'c', 'e', ​​'e', ​​'c', 'd', 'd', 'd', 'd']
пусть myOrderedArray = myArray.уменьшить (функция (аккумулятор, текущее значение) {
  if (аккумулятор.indexOf (currentValue) === -1) {
    аккумулятор.push (currentValue)
  }
  возвратный аккумулятор
}, [])

console.log (myOrderedArray)  

Замените .filter (). map () на .reduce ()

Используя Array.filter () , затем Array.map () просматривает массив дважды, но вы можете добиться того же эффекта, проходя только один раз с помощью Array.reduce () , что делает его более эффективным. (Если вам нравятся петли for, вы может фильтровать и отображать при однократном прохождении с помощью массива .forEach () ).

  постоянные числа = [-5, 6, 2, 0,];

const doubledPositiveNumbers = numbers.reduce ((аккумулятор, currentValue) => {
  if (currentValue> 0) {
    const doubled = currentValue * 2;
    аккумулятор.пуш (сдвоенный);
  }
  возвратный аккумулятор;
}, []);

console.log (doubledPositiveNumbers);  

Выполнение обещаний в последовательности

 
function runPromiseInSequence (arr, input) {
  вернуть arr.reduce (
    (обещание цепочки, текущая функция) => цепочка обещаний.затем (currentFunction),
    Promise.resolve (ввод)
  )
}


функция p1 (a) {
  вернуть новое обещание ((разрешить, отклонить) => {
    решить (a * 5)
  })
}


функция p2 (a) {
  вернуть новое обещание ((разрешить, отклонить) => {
    решить (a * 2)
  })
}


функция f3 (a) {
 вернуть * 3
}


функция p4 (a) {
  вернуть новое обещание ((разрешить, отклонить) => {
    решить (a * 4)
  })
}

const PromiseArr = [p1, p2, f3, p4]
runPromiseInSequence (PromiseArr, 10)
  .then (console.log)
  

Функциональная композиция, обеспечивающая трубопровод

 
const double = х => х + х
константная тройка = х => 3 * х
константная четверка = х => 4 * х


const pipe = (...functions) => input => functions.reduce (
    (acc, fn) => fn (acc),
    Вход
)


const multiply6 = труба (двойная, тройная)
const multiply9 = труба (тройка, тройка)
const multiply16 = труба (четверная, четверная)
const multiply24 = труба (двойная, тройная, четверная)


умножить6 (6)
умножить9 (9)
умножить16 (16)
умножить24 (10)

  

Записать карту, используя сокращение

  if (! Array.prototype.mapUsingReduce) {
  Array.prototype.mapUsingReduce = function (callback, thisArg) {
    верни это.уменьшить (функция (mappedArray, currentValue, index, array) {
      mappedArray [индекс] = callback.call (thisArg, currentValue, индекс, массив)
      вернуть mappedArray
    }, [])
  }
}

[1, 2,, 3] .mapUsingReduce (
  (currentValue, index, array) => currentValue + index + array.length (текущее значение, индекс, массив) => currentValue + index + array.length
)

  

Таблицы BCD загружаются только в браузере

Redux Reducer похож на кофеварку | Адхити Равичандран

Мне нравится думать о редукторе в Redux как о «кофеварке». Он принимает старое состояние и действие и подает новое состояние (свежий кофе).

Redux настолько популярен, что большинство из нас либо использовали его в некоторых проектах, либо слышали о нем. Редукторы - это функции, которые являются частью шаблона Redux и играют решающую роль.

Что такое редуктор? И как мне написать редуктор, не запутавшись?

Мне нравится думать о редукторе как о «кофеварка ». Кофеварка всасывает кофейный порошок и воду. Затем он возвращает чашку свежезаваренного кофе, которым мы можем наслаждаться. По этой аналогии редукторы - это функции, которые принимают текущее состояние (кофейный порошок) и действия (вода) и заваривают новое состояние (свежий кофе).

Редукторы - это чистые функции , которые принимают состояние и действие и возвращают новое состояние.

 function (state, action) => newState 

Редуктор всегда должен следовать следующим правилам:

«Учитывая набор входных данных, он всегда должен возвращать один и тот же результат. Никаких сюрпризов, никаких побочных эффектов. Никаких вызовов API. Никаких мутаций ».

Что такое чистые функции ?? Разве все хорошо написанные функции не чисты ??

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

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

В прошлом мы все писали чистые функции сознательно или неосознанно.

Взгляните на чистую функцию ниже, которая возвращает сумму двух чисел с двумя входными аргументами.

 function sumOfNumbers (a, b) {
return a + b;
}

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

Теперь поговорим о втором требовании о побочных эффектах.

Побочные эффекты возникают всякий раз, когда ваша функция взаимодействует с внешним миром.

Вот несколько примеров общих побочных эффектов:

  • Выполнение вызова API
  • Изменение данных
  • журналы консоли на экране
  • Манипулирование DOM
  • Date.now () для получения текущей даты и времени
  • async вызовы await / ожидание обещаний для разрешения

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

Как только мы поймем, что такое чистая функция, мы все готовы приступить к написанию наших редукторов на redux.

Мы должны помнить, что мы никогда не должны изменять состояние внутри редуктора, и это может быть достигнуто с помощью оператора Object.assign () или последней версии Object Spread (…) .

Никогда не изменять состояние, всегда возвращать новую копию состояния.

Поскольку оператор распространения проще для понимания и поддерживается в последних версиях javascript, я собираюсь использовать его в своем примере.

Оператор распространения объекта концептуально аналогичен оператору расширения массива ES6.

Давайте рассмотрим пример, в котором вы собираетесь оценивать это сообщение в блоге. Наш редуктор примет старое состояние и действие. Действие здесь - RATE_BLOG_POST . Метод редуктора blogDetails () примет текущее состояние и действие в качестве параметров и вернет новое состояние. Снова вспомните аналогию с кофеваркой!

 // Редуктор 
function blogDetails (state = initialState, action) {switch (action.type) {case RATE_BLOG_POST: return {
... state, rating: action.rate
} default: return state
}}

В приведенном выше примере мы всегда будем возвращать новую копию состояния. Оператор распространения (…) гарантирует, что в функции-редукторе нет мутаций состояния.

Это намного проще и читаемее, чем использование метода Object.assign () .

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

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

Написание чистых редукторов приводит к коду, который легко поддерживать, тестировать и отлаживать.

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

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

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

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

Пример ниже показывает инициализацию двух редукторов. combReducers из библиотеки redux обрабатывает агрегирование всех редукторов в приложении. Затем агрегация передается для создания единого хранилища redux.

 import {createStore, combReducers} из "redux"; // Пользовательский редуктор 
const userReducer = function (state = {}, action) {
return state
} // Login Reducer
const loginReducer = function (state = {}, action) {
return state
} // Объединить редукторы
const reducers = combReducers ({
userState: userReducer,
loginState: loginReducer
}) const store = createStore (reducers)

Когда у нас есть несколько редукторов, каждому редуктору передается соответствующая часть общего состояния, а не состояние всего магазина.Как только редукторы выполнят свою работу, они возвращают новое состояние каждого из своих подразделов в магазин.

Шаблон State Reducer с крючками React

Шаблон, который вы можете использовать в пользовательских крючках для повышения мощности и гибкости ваших крючков.

Немного истории

Некоторое время назад я разработал новый шаблон для улучшения ваших компонентов React называется шаблоном редуктора состояния. Я использовал это в пониженную передачу, чтобы включить потрясающую API для людей, которые хотели изменить состояние обновлений при понижении передачи внутренне.

Если вы не знакомы с понижающей передачей, просто знайте, что это «расширенный ввод» компонент, который позволяет создавать такие вещи, как доступные компоненты autocomplete / typeahead / dropdown. Важно знать, что это управляет следующими состояниями: isOpen , selectedItem , выделенIndex , а inputValue .

Понижение передачи в настоящее время реализовано как компонент рендеринга, поскольку время, рендеринг реквизита был лучшим способом сделать «Безголовый компонент пользовательского интерфейса» (обычно реализуется с помощью API "рендеринга"), что позволило вам поделиться логикой, не высказывая мнения о пользовательском интерфейсе.Это основная причина это переключение на пониженную передачу так успешно.

Однако сегодня у нас есть React Hooks и хуки справляются с этим лучше, чем рендеринг реквизита. Итак, я подумал, что дам вам обновленную информацию о том, как этот шаблон переносится на этот новый API, предоставленный нам командой React. (Примечание: В планах понижения передачи есть перехватчик)

Напоминаем, что преимущество шаблона редуктора состояния заключается в том, что он позволяет "инверсия контроля" который, по сути, является механизмом для автора API, позволяющим пользователю API для управления внутренней работой.Для разговора на основе примеров о Я настоятельно рекомендую вам послушать мой доклад на React Rally 2018:

Читайте также в моем блоге: «Инверсия управления»

Итак, в примере с пониженной передачей я принял решение, что когда конечный пользователь выбирает элемент, isOpen должен быть установлен на false (и меню должно быть закрыто). Кто-то создавал множественный выбор с понижающей передачей и хотел сохранить меню открывается после того, как пользователь выбирает элемент в меню (чтобы они могли продолжить чтобы выбрать больше).

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

Использование редуктора состояний с хуками

Итак, концепция выглядит так:

  1. Конечный пользователь выполняет действие
  2. Диспетчерские вызовы разработчика
  3. Хук определяет необходимые изменения
  4. Хук вызывает код разработчика для дальнейших изменений 👈 это инверсия управления part
  5. Hook изменяет состояние

ПРЕДУПРЕЖДЕНИЕ: впереди надуманный пример : Для простоты я собираюсь использовать простой useToggle крючок и компонент в качестве отправной точки.Это будет казаться надуманным, но я не хочу, чтобы вы отвлекались на сложный пример, пока я вас учу как использовать этот узор с крючками. Просто знайте, что этот шаблон лучше всего работает, когда он применяется к сложным крючкам и компонентам (например, переключению на пониженную передачу).

 

1function useToggle () {

2 const [on, setOnState] = React.useState (false)

3

4 const toggle = () => setOnState (o =>! O)

5 const setOn = () => setOnState (true)

6 const setOff = () => setOnState (false)

7

8 return {on, toggle, setOn, setOff}

9}

10

11 Переключение функций () {

12 const {on, toggle, setOn, setOff} = useToggle ()

13

14 return (

15

16

18

19

20)

21}

22

23функция Приложение () {

24 return

25}

26

27ReactDOM.render (, document.getElementById ('root'))

Теперь предположим, что мы хотели настроить компонент , чтобы пользователь нельзя было щелкнуть более 4 раз подряд, если они не щелкнули Кнопка «Сброс»:

 

1function Toggle () {

2 const [clicksSinceReset, setClicksSinceReset] = React.useState (0)

3 const tooManyClicks = clicksSinceReset> = 4

4

5 const {on, toggle , setOn, setOff} = useToggle ()

6

7 function handleClick () {

8 toggle ()

9 setClicksSinceReset (count => count + 1)

10}

11

12 return (

13

14

15

16 <Включить = {on} onClick = {handleClick} />

17 {tooManyClicks? (

18

19): null}

20

21)

22}

Cool, поэтому простым решением этой проблемы было бы добавление if s заявление в handleClick функцию и не вызывать toggle , если tooManyClicks истинно, но давайте продолжим для целей этого примера.

Как в этой ситуации мы могли изменить хук useToggle на , инвертировать элемент управления ? Давайте сначала подумаем об API, а потом уже о реализации. Как пользователь, это было бы было бы здорово, если бы я мог подключаться к каждому обновлению состояния до того, как оно действительно произойдет, и измените его, например:

 

1function Toggle () {

2 const [clicksSinceReset, setClicksSinceReset] = React.useState (0)

3 const tooManyClicks = clicksSinceReset> = 4

4

5 const {on, toggle, setOn, setOff} = useToggle ({

6 modifyStateChange (currentState, changes) {

7 if (tooManyClicks) {

8

9 return {...changes, on: currentState.on}

10} else {

11

12 вернуть изменения

13}

14},

15})

16

17 function handleClick () {

18 toggle ()

19 setClicksSinceReset (count => count + 1)

20}

21

22 return (

23

24

26

27 {tooManyClicks? (

28

29): null}

30

31)

32}

. происходит, когда люди щелкают Кнопки «Выключить» или «Включить», и мы хотим только предотвратить от переключения состояния.

Хммм ... Что, если мы изменим modifyStateChange на reducer и это принимает действие в качестве второго аргумента? Тогда действие могло иметь тип , который определяет, какое изменение происходит, и мы могли бы получить заменяет на toggleReducer , который будет экспортирован с помощью нашего useToggle крюк. Мы просто скажем, что типа для нажатия переключателя - это TOGGLE .

 

1function Toggle () {

2 const [clicksSinceReset, setClicksSinceReset] = React.useState (0)

3 const tooManyClicks = clicksSinceReset> = 4

4

5 const {on, toggle, setOn} = useToggle ({

6 reducer (currentState, action) {

7 const changes = toggleReducer (currentState, action)

8 if (tooManyClicks && action.type === 'TOGGLE') {

9

10 возвращаться {...changes, on: currentState.on}

11} else {

12

13 вернуть изменения

14}

15},

16})

17

18 function handleClick () {

19 toggle ()

20 setClicksSinceReset (count => count + 1)

21}

22

23 return (

24

25

27

28 {tooManyClicks? (

29

30): null}

31

32)

33}

Отлично! Это дает нам всевозможный контроль.И последнее, давайте не будем беспокоиться о строка 'TOGGLE' для типа. Вместо этого у нас будет объект всех изменить типы, на которые люди могут ссылаться. Это поможет избежать опечаток и улучшить автозаполнение редактора (для людей, не использующих TypeScript):

 

1function Toggle () {

2 const [clicksSinceReset, setClicksSinceReset] = React.useState (0)

3 const tooManyClicks = clicksSinceReset> = 4

4

4 9002 5 const {on, toggle, setOn, setOff} = useToggle ({

6 reducer (currentState, action) {

7 const changes = toggleReducer (currenState, action)

8 if (tooManyClicks && action.type === actionTypes.toggle) {

9

10 return {... changes, on: currentState.on}

11} else {

12

13 вернуть изменения

14}

15} ,

16})

17

18 function handleClick () {

19 toggle ()

20 setClicksSinceReset (count => count + 1)

21}

22

23 return (

24

25

26

27 <Включить = {on} onClick = { handleClick} />

28 {tooManyClicks? (

29

30): null}

31

32)

33}

Реализация редуктора состояния с крючками

Хорошо, я ' Я доволен API, который мы здесь раскрываем.Давайте посмотрим, как мы можно реализовать это с помощью нашего хука useToggle . Если вы забыли, вот код для этого:

 

1function useToggle () {

2 const [on, setOnState] = React.useState (false)

3

4 const toggle = () => setOnState (o =>! o)

5 const setOn = () => setOnState (true)

6 const setOff = () => setOnState (false)

7

8 return {on, toggle, setOn, setOff}

9}

Мы, , могли бы добавить логику к каждой из этих вспомогательных функций, но я просто собираюсь чтобы пропустить вперед и сказать вам, что это будет действительно раздражать, даже в этом простой крючок.Вместо этого мы собираемся переписать это с useState на useReducer , и это НАМНОГО упростит нашу реализацию:

 

1function toggleReducer (state, action) {

2 switch (action.type) {

3 case 'TOGGLE': {

4 return {on :! state.on}

5}

6 case 'ON': {

7 return {on: true}

8}

9 case 'OFF': {

10 return {on: false}

11}

12 по умолчанию: {

13 выдать новую ошибку (`Необработанный тип: $ {action.type} `)

14}

15}

16}

17

18function useToggle () {

19 const [{on}, dispatch] = React.useReducer (toggleReducer, {on: false})

20

21 const toggle = () => dispatch ({type: 'TOGGLE'})

22 const setOn = () => dispatch ({type: 'ON'})

23 const setOff = ( ) => отправка ({type: 'OFF'})

24

25 возврат {on, toggle, setOn, setOff}

26}

Хорошо, круто.Действительно быстро, давайте добавим, что вводит свойство в наш useToggle to Избегайте струнных вещей. И мы экспортируем это, чтобы пользователи нашего хука могли сослаться на них:

 

1const actionTypes = {

2 toggle: 'TOGGLE',

3 on: 'ON',

4 off: 'OFF',

5}

6function toggleReducer (состояние, действие) {

7 switch (action.type) {

8 case actionTypes.toggle: {

9 return {on:! State.on}

10}

11 case actionTypes.on: {

12 return {on: true}

13}

14 case actionTypes.off: {

15 return {on: false}

16}

17 по умолчанию: {

18 выбросить новую ошибку (`Необработанный тип: $ {action.type}`)

19}

20}

21}

22

23function useToggle () {

24 const [{on}, dispatch] = React.useReducer (toggleReducer, {on: false})

25

26 const toggle = () => dispatch ({type: actionTypes.toggle})

27 const setOn = () => dispatch ({type: actionTypes.on})

28 const setOff = () => dispatch ({type: actionTypes.off})

29

30 возврат {on, toggle, setOn, setOff}

31}

32

33export {useToggle, actionTypes}

Круто, теперь пользователи передадут редуктор в качестве объекта конфигурации нашему useToggle , поэтому допустим, что:

 

1function useToggle ({reducer}) {

2 const [{on}, dispatch] = React.useReducer (toggleReducer, {on: false})

3

4 const toggle = () => dispatch ({type: actionTypes.toggle})

5 const setOn = () => dispatch ({type: actionTypes. on})

6 const setOff = () => dispatch ({type: actionTypes.off})

7

8 return {on, toggle, setOn, setOff}

9}

Отлично, сейчас что у нас есть редуктор разработчика , как это совместить с нашим редуктором? Что ж, если мы действительно собираемся инвертировать управление для пользователя наш хук, мы не хотим называть наш собственный редуктор .Вместо этого давайте раскроем наши собственные reducer, и они могут использовать его сами, если захотят, поэтому давайте экспортируем его, и тогда мы будем использовать редуктор , который они нам дают вместо нашего:

 

1function useToggle ({reducer}) {

2 const [{on}, dispatch] = React.useReducer (reducer, {on: false })

3

4 const toggle = () => dispatch ({type: actionTypes.toggle})

5 const setOn = () => dispatch ({type: actionTypes.on})

6 const setOff = () => отправка ({type: actionTypes.off})

7

8 return {on, toggle, setOn, setOff}

9}

10

11export {useToggle, actionTypes, toggleReducer}

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

 

1function useToggle ({reducer = toggleReducer} = {}) {

2 const [{on}, dispatch] = React.useReducer (reducer, {on: false})

3

4 const toggle = () => dispatch ({type: actionTypes.toggle})

5 const setOn = () => dispatch ({type: actionTypes. on})

6 const setOff = () => dispatch ({type: actionTypes.off})

7

8 return {on, toggle, setOn, setOff}

9}

10

11export { useToggle, actionTypes, toggleReducer}

Sweet, так что теперь люди могут использовать наш хук useToggle со своим собственным редуктором или можно использовать со встроенным.Любой способ работает так же хорошо.

Заключение

Вот финальная версия:

 

1import * as React from response

2import ReactDOM from react-dom

3import Switch from ./switch

4

5const actionTypes = {

6 переключателей: 'TOGGLE',

7 on: 'ON',

8 off: 'OFF',

9}

10

11 переключение функций Редуктор (состояние, действие) {

12 переключатель (действие .type) {

13 case actionTypes.переключить: {

14 return {on:! state.on}

15}

16 case actionTypes.on: {

17 return {on: true}

18}

19 case actionTypes.off: {

20 возврат {on: false}

21}

22 по умолчанию: {

23 выбросить новую ошибку (`Необработанный тип: $ {action.type}`)

24}

25}

26}

27

28function useToggle ({reducer = toggleReducer} = {}) {

29 const [{on}, dispatch] = React.useReducer (reducer, {on: false})

30

31 const toggle = () => dispatch ({type: actionTypes.toggle})

32 const setOn = () => dispatch ({type: actionTypes. on})

33 const setOff = () => dispatch ({type: actionTypes.off})

34

35 return {on, toggle, setOn, setOff}

36}

37

38

39

40 function Toggle () {

41 const [clicksSinceReset, setClicksSinceReset] = React.useState (0)

42 const tooManyClicks = clicksSinceReset> = 4

43

44 const {on, toggle, setOn, setOff} = useToggle ({

45 reducer (currentState, action) {

46 const changes = toggleReducer (currentState, action)

47 if (tooManyClicks && action.

Разное

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *