Квартирные регуляторы давления воды — для чего нужны, принцып работы, нормативные требования
Уважаемые читатели! С момента публикации этой статьи в ассортименте нашей компании, практике применения оборудования, нормативных документах могли произойти изменения. Предлагаемая вам информация полезна, однако носит исключительно ознакомительный характер.
В однозонной схеме водоснабжения многоэтажного здания с количеством этажей Nи высотой этажа Hэ (рис. 1), в соответствии с п.5.2.10 СП 30.13330.2012, гидростатическое давление на уровне водоразборных приборовверхнего этажа не должно быть ниже РN = 20 м вод. ст.
Рис. 1. Распределение давления в водопроводе многоэтажного дома
В этом случае,на уровне приборов n-ого этажа избыточное давление при однозонной схеме водопровода составит:
Pn = PN+(N – n) · Нэ + Δрln + Δpmn,
где Δpln –линейные потери давления в вышележащем участке стояка; Δpmn – потери давления в тройниках на вышележащих этажах.
Если рассмотреть здание высотой 25 этажей, даже пренебрегая линейными потерями давления и потерями в этажных тройниках, то давление на уровне первого этажа превысит 72 м вод. ст. или 7,2 бара. Это при том, что большинство типов квартирной водоразборной арматуры и водопотребляющего оборудования рассчитано на давление не выше 6 бар. В соответствии с п. 5.2.10 СП 30.13330.2012, гидростатическое давление на отметке наиболее низко расположенного санитарно-технического прибора должно быть не более 0,45 МПа или 4,5 бара.
До недавнего времени проблема снижения давления в системе водопровода многоэтажных зданий решалась путем зонирования. То есть здание по высоте разбивалось на зоны, каждая из которых снабжалась по своему стояку ( рис. 2).
Рис. 2. Распределение давления в водопроводе многоэтажного дома с зонированием
Такие схемы, действительно, прекрасно справлялись с задачей ограничения давления, но имели весьма существенные недостатки. Во-первых, налицо явная низкая экономичность, так как вместо одного стояка приходится прокладывать два. Во-вторых, такие схемы не решали проблему выравнивания давления по этажам. Гидростатическое давление на вводе в квартиру,расположенную в нижнем ярусе зоны, будет всегда заведомо выше, чем у квартир верхнего яруса. Это значит, что в период пикового водоразбора жители этажей верхнего яруса зоны могут остаться без воды.
Появление на рынке достаточно дешевых, компактных и надежных регуляторов давления позволяет отказаться от низкоэкономичных многозонных схем водоснабжения многоэтажных зданий. Регулятор давления, установленный на вводе водопровода в квартиру, позволяет решить сразу несколько задач:
1. Снижение входного давления до требуемого безопасного уровня на всех этажах здания. Это в свою очередь предохраняет внутриквартирныетрубопроводы, арматуру и оборудование от чрезмерных напряжений, продлевая срок их безаварийной эксплуатации.
2. Обеспечение гарантированного расчетного расхода на всех этажах здания. Выравнивая давление по ярусам водопроводного стояка, квартирные редукторы тем самым ограничивают чрезмерный расход в нижних ярусах стояка, что гарантирует получение расчетного расхода воды жителями вышележащих ярусов. Мощный напор из смесителя вовсе не является благом. При срабатывании на вентильной головке смесителя давления свыше 1,3 бара в седле головки возникают разрушающие кавитационные явления, очень быстро выводящие головку из строя.
3. Снижение шумов как в квартирной системе, так и по стояку в целом. Поскольку стояки, как правило, являются сильными резонаторами, то любые акустические эффекты на любом ярусе стояка распространяются по всему стояку. Здание, в котором установлены квартирные регуляторы давления воды, являются практически бесшумными, поскольку скорость потока в таких системах при грамотном расчете и монтаже не превышает 1,5 м/с.
4. Обеспечение комфортного и безопасного режима работы смесителей.
Несбалансированные перепады давления в стояках горячей и холодной воды приводят к изменению настройки температуры смешанной воды на изливе смесителя. Многие, вероятно, сталкивались с таким фактом, когда комфортная температура воды в смесителе вдруг начинала резко меняться либо в сторону крутого кипятка, либо к абсолютно холодной воде. Наличие на квартирных вводах регуляторов давления позволит избавиться от такого неприятного явления.
Нормативные требования к квартирным регуляторам давления
Отечественная нормативная база, регламентирующая требования к бытовым регуляторам давления воды, в настоящее время представлена следующими основными документами:
- ГОСТР 55023 Регуляторы давления квартирные. Общие технические условия
- ГОСТ 12678 Регуляторы давления прямого действия. Основные параметры.
- Методические рекомендации по выбору и применению квартирныхрегуляторов давления в жилых и общественных зданиях (НИИ Сантехники).
Основные требования, предъявляемые к редукторам с Dу = 15 мм, изложенные в перечисленных документах, представлены в табл. 1.
Таблица 1. Нормативные требования к квартирным регуляторам давления
№ | Наименование характеристики | Ед.изм. | Значение |
1 | Условная пропускная способность, не менее | м3/ч | 1,6 (ГОСТ Р 55023) 2,5 (ГОСТ 12678) 1,1 (НИИСантехники) |
2 | Пропускная способность в рабочем диапазоне входных давлений, не менее | м3/ч | 1,8 |
3 | Пропускная способность при входных давлениях ниже рабочего диапазона, не менее | м3/ч | 0,72 |
4 | Рабочий диапазон давления на входе | бар | 3–10 |
5 | Рабочий диапазон расходов | м3/ч | 0,18÷1,8 |
6 | Максимальное выходное давление в рабочем диапазоне расходов, не более | бар | 2,7±0,2 |
7 | Максимальное выходное давление в безрасходном режиме, не более | бар | 3,5 |
8 | Изменение давления при изменении расхода на 0,05 л/с в рабочем диапазоне расходов, не более | бар | 0,04 |
9 | Полный ресурс | тыс. циклов | 250 |
10 | Уровень шума на расстоянии 2 м от прибора | дБА | 40 |
11 | Изгибающий момент на корпус, не менее | Н·м | 80 |
12 | Диапазон температур окружающей среды | ºС | 5–90 |
13 | Допустимая влажность окружающей среды | % | 100 |
14 | Диапазон температур рабочей среды | ºС | 5–90 |
Принцип действия квартирных регуляторов давления
Принцип действия квартирных регуляторов давления основан на уравновешивании усилий, создаваемых давлений на входе и выходе за счет отношенияплощадей, на которые воздействуют эти давления (рис. 3).
Рис. 3. Принцип действия квартирных регуляторов давления
Давление на входе Рвх
Мембранный редуктор VT.085 (рис. 4) применяется в основном в домах повышенной этажности, т.к. рассчитан на номинальное давление 25 бар. Этот редуктор может настраиваться на выходное давление от 1 до 7 бар. Благодаря демпферной камере колебания давления на выходе из редуктора при скачках входного давления не превышают 5 % от настроечного значения. Редуктор поступает в продажу с заводской настройкой на 3 бара.
Рис. 4. Внешний вид и конструкция редуктора VT.085: 1 –корпус, 2 – крышка корпуса, 3 – пробка корпуса, 4 – настроечная втулка, 5 – фиксирующая гайка, 6 – верхняя часть штока, 7 – пружина, 8 – цилиндрическаячасть штока, 9 – мембрана, 10 – распределительное кольцо, 11 – винт золотника с каналом, 12 – золотниковая прокладка, 13 – нижняя часть штока, 14 –уплотнительное кольцо, 15 – демпферная камера
Рис. 5. Внешний вид и конструкция редуктора давления VT.087
Поршневой редуктор VT.087 (рис.5) используется в квартирных узлах ввода, где требуется подстройка редуктора на требуемое расчетное давление. Редуктор рассчитан на номинальноедавление 16 бар и имеет диапазон настройки от 1 до 4,5 бара. Благодаря своей компактности и надежности этот прибор является лидером продаж среди регулирующей арматуры данного класса.
Поршневой редуктор с манометромVT.088 (рис. 6) поставляется компанией VALTEC специально для московских домостроительных комбинатов, которые устанавливают их в типовых узлахобвязки сантехкабин многоэтажных зданий массовых серий. Требование по наличию манометра на выходном канале редуктора изложено в п.7.1.7. СП 30.13330.2012.Редуктор VT.088 рассчитан на номинальное давление 16 бар и имеет диапазон настройки от 1 до 5,5 бара.
Рис. 6. Внешний вид и конструкция редуктора VT.088: 1 – корпус, 2 – корпус пружинной камеры, 3 – крышка корпуса, 4 – шток, 5 – обойма золотника, 6 – малый поршень, 7 – уплотнительное кольцо малого поршня, 8 – большой поршень, 9 – уплотнительное кольцо, 10 –пружина, 11 – винт настройки, 12 – пробка пружинной камеры, 13 – пробка патрубка манометра
Кран с фильтром и редуктором давления VT.298 (рис. 7) является наиболее оптимальным вариантом для квартирного узла ввода водопровода. Этот сверхкомпактный прибор объединяет в себе шаровой угловой кран, фильтр механической очистки с размером ячеи 300 мкм и поршневой редуктор давления с фиксированнойнастройкой на 3,5 бара.
Рис. 7. Внешний вид и конструкция крана с фильтром и редуктором давления VT.298: 1 – большой полукорпус, 2 – малый полукорпус, 3 – пробка, 4 – заглушка, 5 – шток с поршнем, 6 – прокладка, 7 – уплотнительноекольцо, 8 – уплотнительное кольцо, 9 – золотниковая прокладка, 10 – затвор шаровой, 11 – кольцо седельное, 12 – фильтроэлемент, 13 – пружина
Сравнительные данные по регуляторам давления компании VALTEC представлены в табл. 2.
Таблица 2. Технические характеристики регуляторов давления VALTEC с Dу 15 мм
№ | Характеристика | Ед.изм | З | начение для артикулов | ||
VT.085 | VT.087 | VT.088 | VT.298 | |||
1 | Номинальное давление, PN | бар | 25 | 16 | 16 | 16 |
2 | Диапазон настройки | бар | 1– 7 | 1– 4,5 | 1– 5,5 | 3,5 |
3 | Заводская настройка | бар | 3 | 2 | 3 | 3,5 |
4 | Допустимые отклонения от настроечного давления | % | ±5 | ±10 | ±10 | ±10 |
5 | Условная пропускная способность | м3/ч | 2,5 | 1,9 | 1,6 | 1,8 |
6 | Уровень шума, не более | дБА | 30 | 20 | 20 | 40 |
С развернутыми характеристиками регуляторов давления VALTEC,указаниями по их подбору, расчету, монтажу, регулировке и эксплуатации можноознакомиться в технической документации.
Автор: В.И. Поляков
© Правообладатель ООО «Веста Регионы», 2010
Все авторские права защищены. При копировании статьи ссылка на правообладателя
и/или на сайт www.valtec.ru обязательна.
Характерные причины неисправностей квартирных редукторов давления
В. Поляков
Квартирные регуляторы давления сейчас приобретают популярность и часто устанавливаются в квартирах, где смонтированы квартирные узлы ввода и индивидуальные счетчики. По мере массового распространения регуляторов (редукторов) давления, устанавливаемых на вводе в квартиру трубопроводов холодного и горячего водоснабжения, был выявлен ряд специфических требований и определены причины характерных неисправностей этих приборов
Назначение редуктора – как можно точнее поддерживать заданное давление на выходе, независимо от изменений входного давления и потребляемого расхода воды. Это необходимо, чтобы при разной степени водоразбора (на кухне, в ванной, в душе) потребители не чувствовали дискомфорта, и на каждой точке водоразбора с помощью арматуры можно было бы независимо регулировать расход воды в широких пределах.
Важно также, чтобы редуктор поддерживал настроечное давление и при отсутствии водоразбора (в статическом режиме), т. к. это обеспечивает безаварийную работу квартирных трубопроводов, арматуры и приборов.
По принципу действия квартирные редукторы мало чем отличаются от обычных регуляторов давления, работающих по схеме регулирования «после себя» (рис. 1). Это значит, что имеется дроссель (сопротивление), задающий перепад давления. Данный перепад обусловливает определенный расход. При изменении водоразбора изменяется давление после регулятора. Когда меняется давление после регулятора, его рабочий орган перемещается так, чтобы вернуть перепад на дросселе в прежнее (настроенное) значение, то есть стабилизировать расход и вернуть его в первоначальные пределы.
Представим себе коромысло с равными плечами и опорой в точке «О». Коромысло уравновешено двумя поршнями «а» и «b». Входное давление Рвх. давит на малый поршень «а» с силой
F1= Рвх. • Sа,
где Sа – площадь малого поршня.
Давление на выходе Рвых. давит на большой поршень «b» с силой F2 = Рвх.• Sb , где Sb – площадь большого поршня. Поршень «b» подпружинен пружиной F3 = k • х, где k – упругость пружины, а х – величина сжатия пружины.
Таким образом, силы F1 и F3 стремятся открыть клапан, а сила F2 – стремится его закрыть.
В работе регулятора участвуют также силы трения в уплотнениях большого и малого поршня и реактивные гидродинамические силы на дросселирующей кромке.
Рис. 1. Принципиальная схема регулятора давления «после себя»
В мембранных редукторах вместо поршня «b» используется резиновая мембрана.
В связи с тем, что в мембранных редукторах, по сравнению с поршневыми, меньше трущихся поверхностей, надежность и долговечность таких регуляторов больше, но и стоимость таких редукторов выше, чем поршневых.
Условное обозначение простого редуктора давления (см. рис. 2) полностью отражает описанный выше принцип работы – регулируемое сжатие пружины задает настроечное давление, а давление «после себя» Рвых., меняясь из-за изменения расхода в линии, стремится открыть/закрыть клапан так, чтобы расход через редуктор (обусловленный перепадом на рабочей кромке клапана) оставался прежним. Даже при некотором изменении входного давления Рвх. редуктор все равно стремится поддержать настроенный пружиной перепад, а значит и расход в линии после себя.
Рис. 2. Схематическое обозначение редуктора давления
Идеальный редуктор должен иметь практически линейную горизонтальную характеристику во всем диапазоне рабочих давлений. На практике это далеко не так, и в целом типичная характеристика редуктора выглядит, как показано на рис. 3. Гистерезис (Δ) возникает при разном направлении процесса – при увеличении или при снижении расхода (водоразбора), т. е. в какую сторону в данный момент движется рабочий орган (шток с золотником). Причина гистерезиса – нелинейность регулирующих органов, в первую очередь, вызванная трением в соприкасающихся деталях редуктора, зазорами в кинематической цепи регулятора и наличием загрязнений (отложений) на рабочих органах. Это значит, что при одном и том же расходе давление на выходе может быть разным. Особенно это проявляется в поршневых регуляторах давления. В мембранных регуляторах нелинейность присуща самой мембране – в зависимости от величины смещения от нейтрального положения меняется эффективная площадь мембраны, то есть меняется реакция на изменение давления. если гистерезис Δ оказывается свыше 10%, то такой регулятор давления не рекомендуется использовать в качестве квартирного.
Наклон характеристики на горизонтальном участке обусловливает рабочий диапазон регулирования с заданной погрешностью.
Рис. 3. Типовой график расхода редуктора давления при увеличении (синяя кривая) и при снижении расхода (красная линия)
Однако не только точность определяет пригодность редуктора давления для работы в качестве квартирного регулятора. Производители регуляторов давления, как правило, выпускают достаточно широкую линейку редукторов, как мембранных, так и поршневых, конструктивно отличающихся друг от друга пропускной способностью, диапазонами настройки, максимальным коэффициентом редукции, дополнительными опциями и пр. Для примера, в таблице 1 приведены типы регуляторов давления, выпускающихся под торговой маркой VALTEC.
Из приведенной в таблице 1 номенклатуры наибольшим спросом пользуются редукторы, объединенные с шаровым краном и фильтром механической очистки. Они значительно сокращают монтажную длину квартирного узла ввода, недоступны для постороннего вмешательства в заводскую настройку выходного давления и отлично подходят в качестве квартирных регуляторов.
Эксплуатационная надежность и ремонтопригодность – важнейшие показатели, которые зависят от качества самой воды, ее жесткости, чистоты и содержания растворенных газов (воздуха). Помимо этого важна пригодность редуктора для пропуска воды питьевого качества (то есть, использование подходящих материалов), недоступность для несанкционированного вмешательства в настройки – эти и ряд других дополнительных условий выделяют квартирные регуляторы в отдельную группу регулирующей арматуры. Актуальные рекомендации по установке квартирных регуляторов изложены в ДСТУ-Н Б В.3.2-3:2014 «Руководство по выполнению термомодернизации жилых зданий».
Как показал опыт эксплуатации поршневых приборов, при сильно загрязненной воде наблюдается быстрый износ и/или т. н. «закисание» уплотнительных колец поршней. Регуляторы мембранного типа менее подвержены неисправности такого рода.
Таблица 1. Редукторы торговой марки VALTEC
если говорить о наиболее распространенных причинах отказов квартирных регуляторов давления, то самый большой процент нареканий на работу квартирных редукторов вызывает то, что редуктор «не держит» заданное давление в статическом режиме. То есть, при отсутствии водоразбора давление после редуктора растет выше, чем давление настройки.
Рис. 4. Появление капель воды из пружинной камеры – свидетельство износа поршневых уплотнений
В большинстве случаев это связано с попаданием твердых нерастворимых частиц на седло золотника. В результате такого засорения золотник неплотно перекрывает водяной канал и давление за редуктором начинает расти. Редуктор, тем самым, превращается в обычный дроссель. Такой отказ легко устраним простой прочисткой седла и самого золотника. А это значит, перед редуктором нужно обязательно установить запорный вентиль, а сам редуктор должен обладать ремонтоспособностью, предусмотренной конструктивно. если само седло не повреждено, то после прочистки редуктор восстановит свою работоспособность.
Часто недопустимый рост давления за редуктором, стоящим на холодном водопроводе, вовсе не связан с отказом регулятора давления, а вызван другой причиной. Холодная вода с температурой значительно ниже комнатной, поступив в квартирную систему, при отсутствии водоразбора (например, ночью) нагревается до комнатной температуры. Нагрев воды вызывает ее расширение и рост давления уже после редуктора.
Исправить ситуацию можно, установив после редуктора мембранный гаситель гидроударов (что-то вроде расширительного бачка). Пневмоемкость гасителя скомпенсирует излишек воды из-за ее расширения, что не даст давлению на редукторе «после себя» выйти за допустимые пределы.
Еще одной распространенной причиной отказов поршневых редукторов является износ уплотнительных колец большого или малого поршня (см. рис. 4). Интенсивность этого износа существенно зависит от качества подаваемой из водопровода воды. Повышенная жесткость и наличие мелких нерастворимых частиц ведут к активному абразивному воздействию на детали уплотнений.
Фильтры механической очистки, устанавливаемые перед редуктором, а также встроенные фильтры с размером ячеи 200÷500 мкм не могут защитить арматуру от мелких дисперсных частиц. Усугубляет эту ситуацию установка редукторов так, что шток с золотником и поршнями находится в горизонтальном положении. В этом случае нерастворимые частицы скапливаются внизу поршневой камеры и ускоряют износ уплотнителей.
Износ уплотнений проявляет себя появлением капель воды в вентиляционном отверстии пружинной камеры (рис. 4). Как правило, большинство современных квартирных регуляторов давлений ремонтопригодны, поэтому для устранения течи достаточно поменять кольца на поршне, очистить отложения на стенках поршневой камеры, и регулятор давления снова будет способен работать.
Гораздо большую опасность таит в себе неправильный подбор редуктора по расходному режиму. Когда расход через редуктор начинает превышать номинальный, приведенный в таблице 2, а коэффициент редукции (отношение давлений на входе и на выходе) превышает 2,5, то в районе седла возможно появление кавитации.
Сильное дросселирование потока и резкое местное понижение давления вызывает выделение из воды пузырьков водяного пара, которые, схлопываясь, создают локальное повышение давления до нескольких тысяч бар. Мало того, что кавитация вызывает повышенный шум от редуктора, она может полностью разрушить и само седло, и прилегающую к седлу зону, и даже стенку корпуса редуктора (рис. 5 и 6).
Рис. 5. Кавитационное разрушение зоны седла и стенки редуктора
Рис. 6. Кавитационное разрушение золотниковой обоймы редуктораРяд производителей выполняют седло клапана с кольцом из нержавеющей стали, что, по их утверждению, надежно защищает редуктор от последствий кавитации. Но эта мера никак не защищает зону, прилегающую к седлу и стенкам корпуса редуктора.
Таблица 2. Расход через редуктор QN в зависимости от условного диаметра (DN)
Для того, чтобы надежно обезопасить квартирный регулятор давления от кавитации, при его подборе необходимо придерживаться следующих правил:
- Расход через редуктор не должен превышать значений, указанных в таблице 2. Эта таблица по требованиям стандарта DIN EN 1567:2000 рассчитана при скорости потока 2 м/с. Обычная скорость движения воды в трубопроводах внутренних сетей не должна превышать 1,5 м/с.
- Рабочая точка редуктора по соотношению давлений на входе и на выходе должна лежать в зеленой зоне на диаграмме кавитации (рис. 7).
- Потери давления на редукторе (перепад на дросселирующей кромке) по отношению к давлению настройки не должно превышать 1,2 бара.
Рис. 7. Диаграмма кавитации
Что делать, если подобрать квартирный редуктор, удовлетворяющий перечисленным условиям, не удается? Например, давление на входе в редуктор в высотном здании составляет 10 бар, и требуется обеспечить давление на выходе 2,7 бара. По графику на рис. 7 такой редуктор будет работать в зоне возможного возникновения кавитации, т. е. коэффициент при расчетном расходе редукции превышает 2,5. В этом случае требуется каскадное снижение давление, то есть необходимо первый редуктор нужно настроить на давление 4 бара, а следующий − уже на 2,7 бара. Только в этом случае будет обеспечена длительная безаварийная работа регуляторов давлений.
если же эта мера не помогает, то следует выполнить схему разводки по двузонной системе водоснабжения, когда водопроводные стояки по высоте разбиваются на две зоны. Например, в 16-этажном здании стояки первой зоны снабжают этажи с первого по восьмой, а второй зоны – с девятого по шестнадцатый.
Видео. Редуктор давления воды: особенности и настройкаКвартирные регуляторы давления – надежные устройства. Например, порядок испытаний регуляторов на герметичность предполагает циклическое нагружение повышенным давлением не менее 50000 раз. Тем не менее, если соленость воды и степень ее загрязненности механическими частицами в норме, правильно выбран рабочий диапазон давления и рабочая точка регулятора, то выход редуктора из строя вероятен из-за конструктивных и производственных недостатков. Применяйте редукторы только от производителей, которые зарекомендовали себя высоким качеством своих изделий.
Нельзя не упомянуть еще об одном аспекте, связанном с квартирными регуляторами давления воды. Зачастую проектировщики, не утруждая себя сложными расчетами, планируют установку квартирных редукторов в квартирах на всех этажах здания. Но так ли это необходимо? Рекомендуем жильцам, прежде чем бежать в магазин за «правильным» редуктором, замерить давление горячей и холодной воды на входе в квартиру. если это давление не превышает 4,5 бара, и разница между давлениями холодной и горячей воды не превышает 1 бар, то никакого регулятора давления ставить просто не нужно.
Читайте статьи и новости в Telegram-канале AW-Therm. Подписывайтесь на YouTube-канал.
Просмотрено: 36 304Вас может заинтересовать:
Вам также может понравиться
Заказ был отправлен, с Вами свяжется наш менеджер.
≋ Нужен ли бойлеру редуктор давления? • От чего он защитит?
Настала ли пора принимать решение купить бойлер, или же водонагреватель уже приобретен и стоит в коробке у Вас на объекте, следующая задача – правильное его подключение.
Несмотря на многочисленные рекомендации производителей, установка бойлера часто выполняется в полном несоответствии с правилами монтажа. Далеко не всегда такой подход к задаче обусловлен нехваткой денег у потребителя.
Что же чаще всего горе-специалисты «забывают» установить при подключении к водопроводу электрических водонагревателей? Ответ один – редуктор давления.
Рекомендуем товар
11 фото и 1 видео
Редуктор давления воды Caleffi 533441В наличии
Показать цену
Тип: мембранный | Диапазон выходного давления, бар: 1, 6 | Диаметр (дюйм), «: 1/2 | Максимальное давление на входе, бар: 16 | Защита от: динамического давления, статического давления | Подходит: для холодной воды |
Причиной отсутствия редуктора давления зачастую выступает недостаточная квалификация монтажников и незнание последствий такого опрометчивого решения.
Кроме того, далеко не каждый потребитель вникает в тонкости монтажа водонагревательного оборудования и прислушивается к рекомендациям производителя. Как следствие, очень часто при монтаже бойлера своими руками редуктор давления, цена которого не так уж и значительна, попросту не устанавливается. Поэтому рекомендуем купить редуктор давления воды в Одессе и Киеве в нашем магазине, или онлайн.
От чего защитит редуктор давления?
Редуктор давления — устройство небольшое и предназначено именно для уменьшения входного давления воды в водопроводе при подходе к сантехническому, водонагревательному оборудованию, стиральной машинке. Распространен миф о том, что редуктор защитит от гидравлического удара. Гидравлический удар (или гидроудар) появляется из-за мгновенного изменения давления воды в системе водоснабжения. Распространенным последствием высокого давления или гидроудара являются разорванные этим давлением переходные шланги, которые мы не рекомендуем использовать для монтажа. Проявление такого удара характерно также разрушением ослабленных ржавчиной труб и срывом слабых заглушек. При работающем бойлере гидроудар с большой вероятностью может привести к разрыву бака! Так вот именно для защиты от гидродара рекомендуем использовать мембранный гаситель гидроударов.
Обычный бойлер рассчитан на давление поступающей воды до 4 атмосфер – тогда его срок службы будет выше. Различные производители комплектуют бойлеры предохранительными клапанами с разной настройкой (6-9 Бар), при достижении давления свыше настройки клапана, начинается его работа. Сбрасывается избыточное давление части воды из бойлера через специальное отверстие, к слову, контролируйте работу мастера, чтобы он обязательно надел трубку для отвода сбрасываемой воды в канализацию или в подготовленную емкость.
Рекомендуем товар
15 фото и 5 видео
Бойлер Atlantic Steatite Elite VM 80 D400-2-BC 1500WВ наличии
Показать цену
Глубина, мм: 451 | Высота, мм: 811 | Ширина, мм: 433 | Мощность ТЭНа, Вт: 1500 | Тип ТЭНа: сухой | Объем, л: 80 |
Одной из причин постоянно капающего предохранительно-обратного клапана бойлера может служить чрезмерное давление воды (более 8 атмосфер) на входе.
Повышенное давление в трубах может возникнуть не только по причине выхода из строя температурного датчика, но и по вине водоканала, ведь в квартиру вода может подаваться с давлением более 10 атмосфер! Особенно часто такое наблюдается в многоэтажных домах на нижних этажах ночью.
Анализ статистики отказа бойлеров показал, что порядка 70% всех поломок было связано с резким перепадом давления, продолжительными вибрациями.
Если редуктор давления не установлен на входе в квартиру, перед бойлером его установка будет обязательна.
Подключенный на входе в бойлер, редуктор давления станет гарантом защиты от протекающего по причине повышенного давления предохранительного обратного клапана.
Рекомендуем товар
15 фото и 3 видео
Бойлер Ariston VLS EVO DRY 80Под заказ
Показать цену
Глубина, мм: 275 | Высота, мм: 1066 | Ширина, мм: 506 | Мощность ТЭНа, Вт: 1500 | Тип ТЭНа: сухой | Объем, л: 80 |
Грамотный монтаж бойлера: выбор и установка редуктора давления
Какой редуктор давления следует приобрести – решать самому владельцу водонагревателя. Устройства эти различаются:
- По допустимому уровню температуры воды (низкотемпературные – 0-40°С, высокотемпературные – до 130°С).
- По типу (мембранный или поршневой).
- По уровню входного давления воды (до 15, 25, 30 или 60 бар).
- По возможности или невозможности их калибровки, настройки (регулируемые редукторы давления настраиваются вращением винта).
- По наличию или отсутствию места под манометр (и наличию самого манометра в комплекте).
- По материалу корпуса (латунь или ее сплавы) и производителю.
Какой редуктор лучше?
Из-за того, что цена редукторов давления достаточно высока, а скупой платит дважды, доверять стоит только проверенным брендам. Лучшие редукторы выпускают Honeywell (США), ITAP (Италия), Valtec (Италия). Самый дешевый вариант с удовлетворительной надежностью – Honeywell (США) и ITAP (Италия).
Чтобы не столкнуться с подделкой (сегодня подделывается продукция даже именитых брендов), редуктор давления купить рекомендуется в специализированном магазине, а не на рынке.
В любом случае, какой бы редуктор давления Вы не купили, его нужно правильно установить. Монтаж редуктора давления возможен в любой плоскости, как вертикальной так и горизонтальной.
Рекомендуем товар
8 фото и 1 видео
Редуктор давления воды Herz 1/2″ 1268211В наличии
Показать цену
Тип: мембранный | Диапазон выходного давления, бар: 1, 6 | Диаметр (дюйм), «: 1/2 | Максимальное давление на входе, бар: 16 | Защита от: динамического давления, статического давления | Подходит: для холодной воды |
Важно знать: редуктор давления должен быть установлен в строгом соответствии с инструкцией, которая к нему прилагается, силами квалифицированного мастера.
Например, категорически запрещен монтаж «вверх ногами» относительно вертикальной плоскости и «задом наперед» относительно горизонтальной. Корректное направление входа/выхода воды указывается стрелкой на корпусе редуктора.
Стоит помнить и о том, что, как и водяной счетчик, редуктор давления может забиваться ржавчиной и прочим присутствующим в трубах мусором. Установка фильтра грубой очистки перед редуктором (даже если у него имеется встроенный фильтр) — обязательна.
Только специалисты обеспечат правильный монтаж водонагревателя и грамотную установку сопутствующего защитного оборудования, продлевающего срок его службы!
ЧЕТЫРЕ ПРИЧИНЫ установить редуктор давления для БОЙЛЕРА
Почему стоит установить редуктор давления для бойлера: 4 причины
Многие владельцы электрических водонагревателей решают заняться его установкой самостоятельно. Наиболее частым аргументом выступает мнение, что «монтаж такой конструкции по силам каждому». На самом деле, данное мнение является весьма спорным, поскольку установка водонагревателя – это профессиональная задача специалистов, которые могут не только ясно понимать все инструкции по установке, но и четко соблюдать их, опираясь на свой опыт и профессиональную квалификацию.
Не все покупатели понимают истинную важность подключения специального устройства, функция которого заключается в понижении водяного давления до нормальных показателей. Всевозможная техника: стиральная машина, электробойлер, бачок унитаза и прочая, будет слаженно и стабильно работать при давлении 3-4 атм. В современные дома вода поставляется с показателем 10 атм., что может негативно сказаться на функционировании сантехнических предметов и трубах. Следствием повышенного давления становятся утечки, изнашивание, разрывы и прочие неприятности.
Предлагаем к прочтению статью о четырех причинах, которые оправдывают установку редуктора.
Первая причина. Инструкция к электробойлеру.
Стандарт DIN 4753, на который опираются все европейские поставщики электробойлеров, гласит, что перед установкой бойлера необходимо монтировать «группу безопасности». При превышении давления 6 бар в системе, в нее непременно должен быть включен понизитель давления вкупе с обратным клапаном и клапаном излишнего давления.
Изготовители электробойлеров во время продажи устройства, оставляют за собой право не предоставлять гарантийный талон технического обслуживания в том случае, если он был установлен с нарушением прилагаемой к нему инструкции.
Вторая причина. Продление эксплуатационного срока электробойлера.
По статистическим данным, в сервисные центры, занимающиеся ремонтом электробойлеров, более 70% жалоб поступают в связи с поломками, которые вызваны чрезмерным водяным давлением. Одна из самых частых претензий – текущий клапан предохранения во время функционирования прибора. Это может говорить о:
- Поломке самого клапана.
- Поломке термического датчика.
- Водяном давлении, превышающем 8 бар.
Как правило, третий пункт является наиболее часто встречающимся, а после установки редуктора, электробойлер снова работает стабильно и правильно. Особенно важна установка понизителей жителям нижних этажей в многоэтажных домах.
Третья причина. Обеспечение защиты от гидроудара.
Проявление гидроудара наверняка видели многие: он проявляется в виде лопнувших отопительных батарей или разорванных шлангах. Водный удар представляет собой мгновенное повышение скорости потока воды, что вызвано резким поворотом крана или задвижки. Наиболее часто гидроудар наблюдается после полной ликвидации аварий и ремонта систем водоснабжения.
Функционирующий электробойлер, внутри которого находится горячая вода, повышает давление, а потому становится очень подвержен гидроудару. В случае, если клапан предохранения не будет забит, а прибор – не разогрет до максимума, владельца техники огорчит только утечка. Однако, в противном случае, возможен полный разрыв бака по шву сварки, или сильный взрыв, который повлечет за собой не только затяжной ремонт собственного жилья, но и, вероятно, ремонт жилья соседей с нижнего этажа.
Четвертая причина. Уменьшение расходов воды на 50%.
Значительная экономия потребления воды, несомненно, станет весьма мощным стимулом для того, чтобы купить редуктор давления воды для бойлера. Необходимо настроить понизитель на уменьшение водного давления с 9 бар на 4 бар. Настраивая прибор таким образом, его владелец снижает расход воды с 11 до 6 литров в минуту. Следовательно, используя специальные устройства с регулировкой исходного давления, можно существенно сэкономить, особенно при условии проживания в большом доме.
В качестве вывода, следует отметить, что, хотя приобретение понизителя давления обойдется довольно дорого (рекомендуется рассматривать надежные варианты – такие, как итальянские ITAP, Tiemme, или немецкий «Хонивелл»), все равно покупка будет стоить гораздо меньше, чем ремонт дома или квартиры после взрыва бака.
Приобретая редуктор давления для бойлера, человек может не только сэкономить на снабжении водой, но и застраховать себя от множества неприятных последствий, вплоть до взрыва электробойлера в ванной комнате.
Мотор-редукторы, редукторы, электродвигатели Bonfiglioli — от официального представителя в РФ и СНГ
В чем основные преимущества итальянских мотор-редукторов? Прежде всего, это высокое качество и большое разнообразие типоразмеров, комплектаций и опций, достигающееся благодаря модульной конструкции.
Наиболее популярные в промышленности червячные мотор-редукторы представлены сериями VF W и W VF ЕР. Крутящий момент этих редукторов составляет до 9200Нм, передаточное отношение – до 32000. Bonfiglioli производит одноступенчатые, двуступенчатые и цилиндро-червячные приводы. Еще одной отличительной особенностью червячных мотор-редукторов Bonfiglioli является возможность исполнения привода в комплектации EP с защитой от коррозии. Такая комплектация отлично подходит для пищевой, химической и фармацевтической отрасли.
Цилиндрические мотор-редукторы серии А – еще один практически универсальный вариант для промышленных предприятий. КПД этих редукторов выше, чем у червячных агрегатов и при этом они более компактны. Большой выбор комплектаций и опций редукторов позволяет устанавливать их в самое разнообразное оборудование. Крутящий момент редукторов серии А составляет до 14000 Нм, передаточное отношение до 400.
Также обратите внимание на соосные цилиндрические редукторы серии С. Эти редукторы обладают крутящим моментом до 12000Нм, большим диапазоном скоростей и, что немаловажно, демонстрируют отличное соотношение цены и качества.
Планетарные редукторы серии 300 обладают высоким перегрузочным коэффициентом. Возможны различные конфигурации выходного вала и расположения двигателя относительно корпуса редуктора. Крутящий момент этих редукторов составляет до 540000 Нм.
Как выбрать редуктор?
Процессу выбора редуктора следует уделить большое внимание, поскольку от его надежности будут зависеть надежность и производительность оборудования. Наши высококвалифицированные специалисты помогут Вам определить оптимальную модель редуктора или сделать индивидуальный заказ.
В первую очередь необходимо определить коммерческие и технические требования, предъявляемые к приводу. Первый шаг часто упускается из виду, однако, это важная часть процесса проектирования. Вы должны четко осознавать, какие минимальные технические требования будут предъявлены к оборудованию, какие параметры желательны, а какие просто необходимы. В то же время целесообразно определить бюджет.
Далее необходимо выбрать тип привода. Существует большое количество типов мотор-редукторов, каждый из которых обладает рядом преимуществ. На этом этапе необходимо определить, какой из параметров (мощность, эффективность, крутящий момент, срок службы, уровень шума и т.д.) является наиболее значимым для выбранного применения. Для этого Вы можете воспользоваться нашим сервисом по подбору редуктора. Скорее всего, уже сейчас становится очевидным, какая модель редуктора соответствует требуемым показателям крутящего момента и передаточных чисел.
На третьем этапе необходимо оценить дополнительные критерии, такие как габариты, удобство монтажа, соответствие специфическим требованиям. И теперь есть две возможные альтернативы: изготавливать мотор-редуктор на заказ или же приобрести готовую модель. Сосредоточимся сейчас на втором варианте как на более быстром и удобном.
Компания Bonfiglioli предлагает до 12 моделей в рамках серии редукторов, чтобы заказчику не приходилось выбирать между компактными габаритами изделия и коэффициентом запаса по передаваемому моменту. Также возможно заказать мотор-редуктор любой модели в компактном исполнении. Технические характеристики (мощность, момент и передаточные числа) компактного мотор-редуктора такие же, как у полноразмерной модели, а вес и габариты могут быть на 10-15% меньше.
В заключение необходимо установить выбранный Вами мотор-редуктор в образец производимого оборудования и произвести несколько тестовых запусков в условиях, наиболее соответствующих эксплуатационным. Перегрев двигателя, неестественный шум или же очевидное напряжение работы говорят о том, что необходимо повторить процесс выбора или обратиться за консультацией к производителю редуктора.
Хотя процесс выбора мотор-редуктора трудоемкий и длительный, правильно подобранный привод позволит оптимизировать производимую технику и увеличить ее эффективность. С точки зрения конечного пользователя соответствующий оборудованию мотор-редуктор снижает эксплуатационные расходы и повышает производительность.
✔ Какие бывают редукторы? Какой редуктор лучше?
Конический мотор-редуктор
Выбор редуктора – дело вовсе не простое, но мы поможем вам в этом разобраться.
Какие бывают редукторы?
Какой редуктор лучше?
Технические характеристики редукторов.
Основные значения слова «редуктор»
1) Механизм, входящий в приводы машин и служащий для снижения угловых скоростей ведомого вала и повышения крутящих моментов с помощью различных передач. Могут применяться цепные, зубчатые, червячные передачи, а также использоваться их различные сочетания. Существуют комбинированные приводы, в которых редуктор объединяют с вариатором. Редукторы используют в транспортных, грузоподъёмных машинах, обрабатывающих станках и т. п.
2) Устройство для снижения и поддержания постоянным давления рабочей среды (газа, пара или жидкости) на выходе из баллона или другой ёмкости с более высоким давлением, одновременно выполняющее функции предохранительного и запорного клапанов. Редукторы устанавливают в аппаратах для газовой сварки, хлораторах воды и т. п.; используют также в различных установках для осуществления дополнительных операций смешения, подогрева, охлаждения.
Обычно редуктором называют устройство, преобразующее высокую угловую скорость вращения входного вала в более низкую на выходном валу, повышая при этом вращающий момент. Редуктор, который преобразует низкую угловую скорость в более высокую обычно называют мультипликатором. Редуктор, который преобразует высокую угловую скорость в более низкую, обычно называют демультипликатором. Редуктор со ступенчатым изменением передаточного отношения называется коробкой передач, с бесступенчатым — вариатор.
Основными характеристиками редуктора принято считать:
• КПД (коэффициент полезного действия) — основная характеристика измерения эффективности работы любого механического устройства;
• Передаточное отношение характеризует механическую передачу вращательного движения. Редукторы имеют передаточное отношение больше единицы, что показывает понижение скорости. Отсюда второе название механизма — понижающий механический редуктор;
• Мощность передачи;
• Угловые скорости вращения механических элементов — валов;
• Количество ведущих и ведомых валов;
• Вид и количество ступеней передачи.
Сотни миллионов редукторов ежедневно работают во всех странах мира, на суше, в воздухе и в воде. Этот агрегат уже не один десяток лет активно применяется в самых различных отраслях технико- и приборостроения. Наибольшим спросом редуктор пользуется в автомобильной промышленности, в частности в производстве деталей для автомобилей. Производят редукторы по всему миру, как в России, так и за рубежом, в частности – в Италии (компании Bonfiglioli, Motovario, Chiaravalli и др.)
Многообразие сфер использования редукторов предопределило огромное количество разновидностей его конструкции. Можно встретить такие понятия, как общепромышленные, газовые редукторы, мотор-редукторы. Существуют и другие вариации, такие как мультипликатор, или вариатор, турборедуктор, цилиндрический, конический, червячный, планетарный, волновой редуктор.
Названия различных вариаций редукторов слагаются исходя из особенностей их конструкции. Так, например, червячный мотор-редуктор подразумевает применение в своей конструкции червячной передачи. Она характеризуется относительной бесшумностью работы и небольшими размерами.
Корпус обычного редуктора имеет стандартную литую форму. Редуктор, который принято использовать в тяжелой промышленности или в машиностроении, имеет корпус из литейного чугуна. Также встречаются корпуса из литейной стали. Легкосплавные корпуса встречаются все чаще и чаще в повседневной жизни, так как такой корпус значительно облегчает конструкцию редуктора.
Большинство специалистов считают создателем первого простейшего редуктора Архимеда. Именно он, спроектировав и создав приспособление, отдаленно напоминающее современный редуктор (по крайней мере, по принципам функционирования и целям создания), дал возможность жителям своего родного города Сиракузы без особых усилий вытаскивать на сушу и сдвигать с места захваченные вражеские корабли. Конечно, на протяжении веков конструкция и размеры редуктора изменялись и совершенствовались, и сегодня механизм ни чем не напоминает своего первого предка, но принцип действия остался прежним.
Устройство червячного редуктора | Компания «Ф и Ф»
Червячный редуктор относится к наиболее популярным типам механических передаточных систем, что обусловлено целым рядом технических и эксплуатационных преимуществ. Рассмотрим, что представляет собой червячный редуктор, устройство и принцип работы данного устройства.
Навигация по статье
Конструкция и геометрические размеры
Сфера применения редукторов
Конструкция и геометрические размеры
Устройство редуктора червячного типа включает два основных элемента образующих зацепление — винт или «червяк» и червячное колесо. Последнее является разновидностью косозубого колеса. В данной паре винт является ведущим звеном, колесо — ведомым. Одним из основных отличий от цилиндрического и прочих типов редукторов является большая плоскость зацепления и высокое передаточное отношение, что приводит к самоторможению устройства. В зависимости от того, в каких механизмах применяется данное устройство, данная конструктивная особенность может быть как достоинством, так и недостатком.
Теперь о том, как работает червячный редуктор. Передаваемое на входной вал с червяком крутящее усилие приводит к вращению винта. В свою очередь винт толкает зубчатое колесо, обеспечивая передачу крутящего момента. В отличие от цилиндрических и конических передач, данная связка работает со значительным уменьшением угловой скорости (передаточное отношение до 110 на одной ступени) и увеличением крутящего усилия.
При одинаковом принципе работы червячных редукторов они значительно различаются по передаточному числу и геометрии зацепления. Оси винта и колеса расположены под прямым углом относительно друг друга.
По конфигурации поверхности с резьбой червяки подразделяются на цилиндрические и глобоидные. По форме профиля они делятся на:
- Архимедовы червяки. Имеют прямолинейный трапециидальный профиль в осевом сечении. В торцевом очерчены архимедовой спиралью.
- Конволюнтные — прямолинейный профиль в сечении, нормальный к виткам червяка.
- Эвольвентные. Червяк в торцовом сечении имеет эвольвентный профиль.
Винт может иметь один или несколько заходов, их количество выбирается в зависимости от передаточного отношения. Стандартным количеством заходов является 1, 2 и 4.
Сфера применения редукторов
Конструктивные особенности и принцип работы червячного редуктора обусловили его сферу применения. В первую очередь, это необходимость снижения частоты вращения привода и значительного увеличения крутящего момента. Главным же ограничением является отсутствие больших ударных нагрузок и малая периодичность включений.
В целом применение червячного редуктора должно соответствовать следующим рекомендациям:
- Если механизму не требуется работать с самоторможением и при передаточном числе менее 25 во многих случаях оптимальным вариантом будет применение цилиндро-червячных редукторов. Они обладают большим КПД, имеют более высокий ресурс работы и позволяют сэкономить электроэнергию.
- Учитывайте ударную нагрузку. Сам принцип работы червячного редуктора и его конструкция обуславливают высокую чувствительность к ударам, что приводит к перегреву и значительному снижению ресурса работы устройства.
- Во многом работа червячного редуктора зависит от схемы его расположения в пространстве. Базовым и наиболее рекомендуемым вариантом является размещение оси винта внизу, а оси зубчатого колеса вверху.
Применение редуктора червячного типа — это низкая шумность и высокая плавность работы, большое передаточное число, что позволяет значительно сэкономить пространство. Последнее особенно важно при проектировании мотор редукторов и обеспечивает широкое применение червячных устройств в современных машинах и механизмах.
Основы Redux, часть 3: Состояние, действия и редукторы
- Как определить значения состояния, которые содержат данные вашего приложения
- Как определить объекты действий, которые описывают, что происходит в вашем приложении
- Как написать функции редуктора, которые вычисляют обновленные состояние на основе существующего состояния и действий
Введение #
В части 2: Концепции Redux и поток данных мы рассмотрели, как Redux может помочь нам создавать поддерживаемые приложения, предоставляя нам единое центральное место для размещения глобального состояния приложения.Мы также обсудили основные концепции Redux, такие как диспетчеризация объектов действий и использование функций-редукторов, которые возвращают новые значения состояния.
Теперь, когда у вас есть некоторое представление о том, что это за штуки, пора применить эти знания на практике. Мы собираемся создать небольшой пример приложения, чтобы увидеть, как эти части на самом деле работают вместе.
Пример приложения не является полным готовым к производству проектом . Цель состоит в том, чтобы помочь вам изучить основные API-интерфейсы Redux и шаблоны использования, а также указать правильное направление, используя несколько ограниченных примеров.Кроме того, некоторые из первых элементов, которые мы создаем, будут обновлены позже, чтобы показать более эффективные способы работы. Пожалуйста, прочтите весь учебник, чтобы увидеть все используемые концепции. .
Настройка проекта №
Для этого руководства мы создали предварительно настроенный стартовый проект, в котором уже настроен React, есть некоторые стили по умолчанию и есть поддельный REST API, который позволит нам писать фактические запросы API в нашем приложение. Вы будете использовать это как основу для написания фактического кода приложения.
Для начала вы можете открыть этот CodeSandbox и разветвить его:
Вы также можете клонировать тот же проект из этого репозитория Github. После клонирования репо вы можете установить инструменты для проекта с npm install
и запустить его с npm start
.
Если вы хотите увидеть окончательную версию того, что мы собираемся построить, вы можете проверить шагов руководства
ветка или посмотреть окончательную версию в этом 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 с помощью компонента
ReactDOM.render ( , document.getElementById ('root'))
КопироватьИзучение исходного проекта #
Этот первоначальный проект основан на стандартном Create-React -Шаблон проекта приложения, с некоторыми изменениями.
Давайте быстро посмотрим, что содержит исходный проект:
-
/ src
-
index.js
: файл точки входа для приложения. Он отображает основной компонент -
App.js
: основной компонент приложения. -
index.css
: стили для всего приложения -
/ api
-
client.js
: небольшой клиент запросов AJAX, который позволяет нам делать запросы GET и POST -
server.js
: предоставляет поддельный REST API для наших данных. Наше приложение будет получать данные с этих поддельных конечных точек позже.
-
-
/ exampleAddons
: содержит некоторые дополнительные надстройки Redux, которые мы будем использовать позже в руководстве, чтобы показать, как все работает
-
Если вы загрузите приложение сейчас, вы должны увидеть приветственное сообщение, но все остальное приложения в противном случае пусто.
Итак, приступим!
Запуск примера приложения Todo #
Нашим примером приложения будет небольшое приложение «todo». Вы, наверное, видели примеры приложений todo раньше — они делают хорошие примеры, потому что они позволяют нам показать, как делать такие вещи, как отслеживание списка элементов, обработка пользовательского ввода и обновление пользовательский интерфейс при изменении этих данных, что происходит в обычном приложении.
Определение требований #
Начнем с определения начальных бизнес-требований для этого приложения:
- Пользовательский интерфейс должен состоять из трех основных разделов:
- Поле ввода, позволяющее пользователю вводить текст нового элемента задачи.
- Список всех существующих задач
- Нижний колонтитул, в котором отображается количество незавершенных задач и параметры фильтрации.
- Элементы списка задач должны иметь флажок, который переключает их статус «выполнено».Мы также должны иметь возможность добавить цветной тег категории для предопределенного списка цветов и удаление элементов списка дел.
- На счетчике должно быть число активных задач во множественном числе: «0 элементов», «1 элемент», «3 элемента» и т. Д.
- Должны быть кнопки, чтобы отметить все задачи как выполненные и очистить все завершенные задачи путем их удаления.
- Должно быть два способа фильтрации отображаемых задач в списке:
- Фильтрация на основе отображения «Все», «Активные» и «Завершенные» задачи
- Фильтрация на основе выбора одного или нескольких цветов и отображение любых задач. чей тег соответствует этим цветам
Позже мы добавим еще несколько требований, но этого достаточно для начала.
Конечная цель — это приложение, которое должно выглядеть так:
Проектирование значений состояния #
Один из основных принципов React и Redux заключается в том, что ваш пользовательский интерфейс должен основываться на вашем состоянии . Итак, один из подходов к разработке приложения — сначала подумать обо всех состояниях, необходимых для описания того, как приложение работает. Это тоже хорошая идея чтобы попытаться описать свой пользовательский интерфейс с как можно меньшим количеством значений состояния, чтобы было меньше данных, которые вам нужно отслеживать и обновить.
Концептуально это приложение имеет два основных аспекта:
- Фактический список текущих задач
- Текущие параметры фильтрации
Нам также необходимо отслеживать данные, которые пользователь вводит в поле » Поле ввода «Добавить Todo», но это менее важно и мы разберемся с этим позже.
Для каждого элемента todo нам нужно сохранить несколько фрагментов информации:
- Текст, введенный пользователем
- Логический флаг, указывающий, завершено оно или нет
- Уникальное значение ID
- Цветовая категория, если выбрана
Наше поведение фильтрации, вероятно, можно описать с помощью некоторых перечислимых значений:
- Завершенный статус: «Все», «Активно» и «Завершено»
- Цвета: «Красный», «Желтый», «Зеленый», » Синий »,« Оранжевый »,« Фиолетовый »
Глядя на эти значения, мы также можем сказать, что задачи — это« состояние приложения »(основные данные, с которыми работает приложение), в то время как значения фильтрации — «состояние пользовательского интерфейса» (состояние, описывающее, что приложение делает прямо сейчас).Это может быть полезно подумайте об этих различных категориях, чтобы понять, как используются различные части состояния.
Проектирование структуры состояний #
В Redux, состояние нашего приложения всегда хранится в простых объектах JavaScript и массивах . Это означает, что вы не можете ставить
другие вещи в состоянии Redux — нет экземпляров классов, встроенные типы JS, такие как Map
/ Set
Promise
/ Date
, функции или что-либо еще, что не является простыми данными JS.
Значение корневого состояния Redux почти всегда представляет собой простой объект JS с другими данными, вложенными в него.
Основываясь на этой информации, мы теперь можем описать типы значений, которые нам нужны в нашем состоянии Redux:
- Во-первых, нам нужен массив объектов todo item. Каждый элемент должен иметь следующие поля:
-
id
: уникальный номер -
текст
: текст, введенный пользователем -
завершен
: логический флаг -
цвет
: дополнительная цветовая категория
-
- Затем нам нужно описать наши параметры фильтрации.Нам необходимо:
- Текущее «завершенное» значение фильтра
- Массив текущих выбранных цветовых категорий
Итак, вот как может выглядеть пример состояния нашего приложения:
const todoAppState = { задачи: [{id: 0, текст: 'Learn React', завершено: true}, {id: 1, text: 'Learn Redux', выполнено: false, color: 'purple'}, {id: 2, text: «Постройте что-нибудь забавное!», Завершено: false, цвет: «синий»}], фильтры: {статус: «Активный», цвета: [«красный», «синий»]}}
КопироватьВажно отметить, что — это нормально иметь другие значения состояния вне Redux! .Этот пример пока достаточно мал, чтобы у нас действительно было все наше состояние в хранилище Redux, но, как мы увидим позже, некоторые данные действительно не нужно хранить в Redux (например, «открыт ли этот раскрывающийся список?» Или «текущее значение формы ввода»).
Разработка действий #
Действия — это простые объекты JavaScript, которые имеют поле типа
. Как упоминалось ранее, вы можете думать о действии как о событии, которое описывает что-то, что произошло в приложении .
Точно так же, как мы разработали структуру состояний на основе требований приложения, мы также должны иметь возможность составьте список некоторых действий, описывающих происходящее:
- Добавить новую запись задачи на основе текста, введенного пользователем
- Переключить завершенный статус задачи
- Выбрать цветовую категорию для задачи
- Удалить задачу
- Отметить все задачи как выполненные
- Очистить все завершенные задачи
- Выбрать другое значение фильтра «Завершено»
- Добавить новый цветной фильтр
- Удалить цветной фильтр
Обычно мы помещаем любые дополнительные данные, необходимые для опишите, что происходит в акции .поле полезной нагрузки
. Это могло быть
число, строка или объект с несколькими полями внутри.
Хранилище Redux не заботится о фактическом тексте поля action.type
. Однако ваш собственный код будет выглядеть
в action. введите
, чтобы узнать, требуется ли обновление. Кроме того, вы часто будете смотреть на строки типа действия в Redux.
DevTools Extension во время отладки, чтобы узнать, что происходит в вашем приложении. Итак, попробуйте выбрать типы действий, которые
читабельны и четко описывают, что происходит — вам будет намного легче понять вещи, когда вы посмотрите на них позже!
На основе этого списка вещей, которые могут произойти, мы можем создать список действий, которые будет использовать наше приложение:
-
{type: 'todos / todoAdded', payload: todoText}
-
{type: ' todos / todoToggled ', полезная нагрузка: todoId}
-
{тип:' todos / colorSelected, полезная нагрузка: {todoId, color}}
-
{тип: 'todos / todoDeleted', полезная нагрузка: 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. Затем мы можем написать схему логики внутри функции редуктора:
src / reducer.js
const initialState = {todos: [{id: 0, text: 'Learn React', completed: true}, { id: 1, текст: 'Learn Redux', завершено: false, цвет: 'purple'}, {id: 2, text: 'Постройте что-нибудь забавное!', выполнено: false, color: 'blue'}], фильтры: {статус: 'Все', цвета: []}}
экспортировать функцию по умолчанию appReducer (state = initialState, action) {switch (action.type) {default: return state}}
Копировать Редуктор может быть вызван с undefined
в качестве значения состояния при инициализации приложения. Если это произойдет, нам нужно предоставить значение начального состояния, чтобы остальной части кода редуктора было с чем работать. Редукторы обычно используют синтаксис аргумента по умолчанию ES6 для предоставления начального состояния: (state = initialState, action)
.
Затем давайте добавим логику для обработки действия todos / todoAdded
.
Мы знаем, что нам нужно проверить, соответствует ли тип текущего действия этой конкретной строке. Затем нам нужно вернуть новый объект, содержащий всех состояний, даже для полей это не изменилось.
src / reducer.js
function nextTodoId (todos) {const maxId = todos.reduce ((maxId, todo) => Math.max (todo.id, maxId), -1) return maxId + 1}
экспортировать функцию по умолчанию appReducer (state = initialState, action) {switch (action.type) {case 'todos / todoAdded': {return {...state, todos: [... state.todos, {id: nextTodoId (state.todos), text: action.payload, completed: false}]}} default: return state}}
КопироватьЭто .. Ужасно много работы, чтобы добавить в состояние одну задачу. Зачем нужна вся эта дополнительная работа?
Правила редукторов #
Ранее мы говорили, что редукторы должны всегда следовать некоторым особым правилам :
- Они должны вычислять только новое значение состояния на основе состояния
- Они являются не разрешено изменять существующее состояние
- Они не должны выполнять асинхронную логику или другие «побочные эффекты».
«Побочный эффект» — это любое изменение состояния или поведения, которое можно увидеть за пределами возврата значения из функции . Вот некоторые распространенные побочные эффекты:
- Запись значения в консоль
- Сохранение файла
- Установка асинхронного таймера
- Выполнение HTTP-запроса AJAX
- Изменение некоторого состояния, которое существует вне функции, или изменение аргументов функции
- Генерация случайных чисел или уникальных случайных идентификаторов (например,
Math.random ()
илиDate.now ()
)
Любая функция, которая следует этим правилам, также известна как «чистая» функция , даже если она специально не написана как функция-редуктор.
Но почему эти правила важны? Есть несколько разных причин:
- Одна из целей Redux — сделать ваш код предсказуемым. Когда вывод функции рассчитывается только на основе входных аргументов, легче понять, как работает этот код, и протестировать его.
- С другой стороны, если функция зависит от внешних переменных или ведет себя случайным образом, вы никогда не знаете, что произойдет, когда вы ее запустите.
- Если функция изменяет другие значения, включая аргументы, это может неожиданно изменить способ работы приложения. Это может быть частым источником ошибок, таких как «Я обновил свое состояние, но теперь мой пользовательский интерфейс не обновляется, когда должен!»
- Некоторые возможности Redux DevTools зависят от того, правильно ли ваши редукторы соблюдают эти правила.
Правило о «неизменяемых обновлениях» особенно важно, и о нем стоит поговорить далее.
Редукторы и неизменяемые обновления #
Ранее мы говорили о «мутации» (изменение существующих значений объекта / массива) и «неизменности» (обработка значений как чего-то, что нельзя изменить).
В Redux, наши редукторы никогда не позволяют изменять исходные / текущие значения состояния!
Существует несколько причин, по которым вы не должны изменять состояние в Redux:
- Это вызывает ошибки, такие как некорректное обновление пользовательского интерфейса для отображения последних значений
- Это затрудняет понимание того, почему и как состояние было изменено. обновлено
- Это затрудняет написание тестов
- Это нарушает способность правильно использовать «отладку во времени»
- Это идет вразрез с предполагаемым духом и шаблонами использования для Redux
Итак, если мы не можем изменить оригиналы , как вернуть обновленное состояние?
Редукторы могут делать только копий исходных значений, а затем они могут изменять копии.
return {... state, value: 123}
CopyМы уже видели, что можем писать неизменяемые обновления вручную, используя операторы распределения массива / объекта JavaScript и другие функции, которые возвращают копии исходных значений.
Это становится сложнее, если данные вложены. Критическое правило неизменяемых обновлений состоит в том, что вы должны делать копию каждые уровней вложенности, которые необходимо обновить.
Однако, если вы думаете, что «написание неизменяемых обновлений вручную таким образом будет трудно запомнить и сделать правильно»… Да, ты прав! 🙂
Написание неизменяемой логики обновления вручную — это сложно, а , случайно изменяющее состояние в редукторах, является единственной наиболее частой ошибкой, которую делают пользователи Redux .
В реальных приложениях вам не придется вручную писать эти сложные вложенные неизменяемые обновления . В части 8: Современный Redux с Redux Toolkit вы узнайте, как использовать Redux Toolkit для упрощения написания неизменной логики обновления в редукторах.
Обработка дополнительных действий #
Имея это в виду, давайте добавим логику редуктора еще для пары случаев.Во-первых, переключение поля задачи завершено
на основе его идентификатора:
src / reducer.js
экспортная функция по умолчанию appReducer (state = initialState, action) {switch (action.type) {case 'todos / todoAdded': {return {... state, todos: [... state.todos, {id: nextTodoId (state.todos), text: action.payload, completed: false}]}} case 'todos / todoToggled': {return {...state, задачи: state.todos.map (todo => {if (todo.id! == action.payload) {return todo}
return {... todo, completed:! todo.completed}})}} default: return state}}
КопироватьИ поскольку мы сосредоточились на состоянии задач, давайте добавим случай для обработки «выбора видимости также изменилось действие «:
src / reducer.js
экспорт функции по умолчанию appReducer (state = initialState, action) {switch (action.type) {case 'todos / todoAdded': {return {... state, todos: [... state.todos, {id: nextTodoId (state.todos), text: action.payload, completed: false}]} } case 'todos / todoToggled': {return {... state, todos: state.todos.map (todo => {if (todo.id! == action.payload) {return todo})
return {... todo, завершено:! todo.завершено}})}} case 'filters / statusFilterChanged': {return {... state, filters: {... state.filters, status: action.payload}}} по умолчанию: return state}}
КопироватьМы обработал всего 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
const initialState = [{id: 0, текст: 'Learn React', завершено: true}, {id: 1, text: 'Learn Redux', выполнено: false, цвет: 'purple'}, {id: 2, text: 'Постройте что-нибудь забавное!', завершено : false, color: 'blue'}]
функция nextTodoId (todos) {const maxId = todos.reduce ((maxId, todo) => Math.max (todo.id, maxId), -1) return maxId + 1}
экспортировать функцию по умолчанию todosReducer (state = initialState, action) {switch (action.type) {default: return state}}
КопироватьТеперь мы можем скопировать логику обновления задач. Однако здесь есть важное отличие. Этот файл должен обновлять только состояние, связанное с задачами — он больше не вложен! Это еще одна причина, по которой мы разделили редукторы. Поскольку состояние задач — это сам по себе массив, нам не нужно копировать сюда внешний объект корневого состояния.Это упрощает чтение этого редуктора.
Это называется составом редуктора , и это фундаментальный образец построения приложений Redux.
Вот как выглядит обновленный редуктор после того, как мы обработаем эти действия:
src / features / todos / todosSlice.js
экспортировать функцию по умолчанию todosReducer (state = initialState, action) {switch (action.type) {case ' todos / todoAdded ': {return [... state, {id: nextTodoId (state), text: action.полезная нагрузка, завершено: false}]} case 'todos / todoToggled': {return state.map (todo => {if (todo.id! == action.payload) {return todo}
return {... todo, completed:! todo.completed}})} default: return state}}
КопироватьЭто немного короче и легче для чтения.
Теперь мы можем сделать то же самое с логикой видимости. Создайте src / features / filters / filtersSlice.js
, и переместим туда весь код, связанный с фильтрами:
src / features / filters / filtersSlice.js
const initialState = {status: 'All', colors: []}
экспортировать функцию по умолчанию FiltersReducer (state = initialState, action) {switch (action.type) {case 'filters / statusFilterChanged': {return {... state, status: action.payload}} default: return state}}
КопироватьНам все еще нужно скопировать объект, содержащий состояние фильтров, но, поскольку вложения меньше, легче читать, что происходит.
Объединение редукторов #
Теперь у нас есть два отдельных файла срезов, каждый со своей собственной функцией редуктора срезов. Но, как мы уже говорили ранее, при создании хранилища Redux требуется и одна функция корневого редуктора . Итак, как мы можем вернуться к корневому редуктору, не помещая весь код в одну большую функцию?
Поскольку редукторы являются обычными функциями JS, мы можем импортировать редукторы фрагментов обратно в файл reducer.js
и написать новый корневой редуктор, единственная задача которого — вызывать две другие функции.
src / reducer.js
импортировать todosReducer из './features/todos/todosSlice'import filtersReducer из' ./features/filters/filtersSlice '
экспортировать функцию по умолчанию rootReducer (state = {}, action) {return {todos: todosReducer (state.todos, action), filters: filtersReducer (state.filters, action)}}
КопироватьОбратите внимание, что каждый из этих редукторов управление собственной частью глобального государства. Параметр состояния отличается для каждого редуктора и соответствует части состояния, которым он управляет.
Это позволяет нам разделить нашу логику на основе функций и срезов состояния, чтобы поддерживать удобство обслуживания.
combReducers
#Мы видим, что новый корневой редуктор делает то же самое для каждого фрагмента: вызывает редуктор фрагмента, передает фрагмент состояния, принадлежащего этому редуктору, и присваивает результат обратно корню. государственный объект. Если бы мы добавили больше срезов, узор повторил бы.
В базовую библиотеку Redux входит утилита combReducers
, которая выполняет тот же шаблонный шаг за нас.Мы можем заменить наш рукописный rootReducer
на более короткий, созданный combReducers
.
Теперь, когда нам нужно combReducers
, пришло время фактически установить базовую библиотеку Redux :
Как только это будет сделано, мы можем импортировать combReducers
и использовать его:
src / reducer.js
import { combReducers} из "redux"
импортировать todosReducer из './features/todos/todosSlice'import filtersReducer из'./ features / filters / filtersSlice '
const rootReducer = combReducers ({todos: todosReducer, filters: filtersReducer})
экспорт по умолчанию rootReducer
Копировать combReducers
принимает объект, имена ключей которого станут ключами в вашем объекте корневого состояния, а
Значения — это функции редуктора среза, которые знают, как обновлять эти срезы состояния Redux.
Помните, имена ключей, которые вы даете combReducers
, определяют, какими будут имена ключей вашего объекта состояния!
Что вы узнали #
Состояние, действия и редукторы являются строительными блоками Redux .Каждое приложение Redux имеет значения состояния, создает действия для описания того, что произошло, и использует функции редуктора для вычисления новых значений состояния на основе предыдущего состояния и действия.
Вот содержимое нашего приложения на данный момент:
- Приложения Redux используют простые объекты JS, массивы и примитивы в качестве значений состояния
- Значение корневого состояния должно быть простым объектом JS
- Состояние должно содержать наименьший объем данных, необходимый для работы приложения
- Классы, обещания, функции и другие непростые значения, если не перейдут в состояние Redux
- Редукторы не должны создавать случайные значения, такие как
Math.random ()
илиDate.now ()
- Это нормально, если другие значения состояния, которых нет в хранилище Redux (например, состояние локального компонента), бок о бок с Redux
- Действия представляют собой простые объекты с поле
типа
, описывающее, что произошло- Поле
типа
должно быть читаемой строкой и обычно записывается как'feature / eventName'
- Действия могут содержать другие значения, которые обычно хранятся в
действие.полезная нагрузка
поле - Действия должны иметь наименьший объем данных, необходимых для описания того, что произошло
- Поле
- Редукторы — это функции, которые выглядят как
(состояние, действие) => newState
- Редукторы всегда должны следовать особым правилам:
- Вычислять новое состояние только на основе состояния
аргументы
- Никогда не изменять существующее состояние
- Нет «побочных эффектов», таких как вызовы AJAX или асинхронная логика
- Вычислять новое состояние только на основе состояния
- Редукторы всегда должны следовать особым правилам:
- Редукторы должны быть разделены, чтобы их было легче читать.
- Редукторы обычно разделяются на основе ключей состояния верхнего уровня или «фрагментов» состояния
- Редукторы обычно записываются в файлы «фрагментов», организованные в папки «функций»
- Редукторы можно комбинировать вместе с Redux.
.
определяют ключи объекта состояния верхнего уровня
Что дальше? #
Теперь у нас есть некоторая логика редуктора, которая обновит наше состояние, но эти редукторы ничего не сделают сами.Им нужно быть помещенным в хранилище Redux, которое может вызывать код редуктора с действиями, когда что-то происходит.
В части 4: Store мы увидим, как создать хранилище Redux и запустить нашу логику редуктора.
Понимание того, как редукторы используются в 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, стоит проверить официальную документацию.
Что такое редуктор в 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
, он может быть более читаемым и доступным для новичков в этой концепции. Однако имейте в виду, что счетчик
по-прежнему является состоянием:
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.
Вы можете использовать их без Redux
от Райана Юрканина
Фото Сораи Ирвинг на UnsplashTL; DR: Вы можете обрабатывать состояние с помощью редуктора в компонентах класса, имея одну функцию, которая переводит действия в изменения состояния.Он централизует все ваши setStates.
? Что такое редуктор?
Редукторы — это функции, которые принимают входные данные и решают, что с ними делать, в одном центральном месте. Вот и все. ?
Если у вас есть функция, которая определяет отображаемое представление на основе URL-адреса, это редуктор.
Redux Reducers ™ ️ — это конкретное использование редукторов, которые интерпретируют события в вашем приложении и то, как это меняет состояние приложения.
this.dispatch («RESET_COUNT_CLICKED») Если вы не знакомы с Redux, приведенный выше пример обычно запускается путем вызова функции dispatch
с действием
(объект, описывающий событие).?
Мы можем использовать редукторы прямо сейчас в компоненте класса, создав функцию, которая обрабатывает установку состояния с помощью типа действия, например:
Использование редуктора в этом простом примере, на мой взгляд, является излишним. Я рад, что React собирается предоставить по этой причине хуки useState
и useReducer
.
Если бы я заметил, что передаю способы изменения состояния, и счетчик
стал связан с еще несколькими свойствами состояния, я бы переключился на редуктор.
Поскольку Redux помещает все свое состояние в один объект, который быстро растет, он идеально подходит для шаблона редуктора. Из Redux можно удалить редукторы, даже если мы потеряем массу замечательных функций.
Redux позволяет подключить
глобальное хранилище к вашему компоненту. Вы можете перевести состояние в реквизит. Они также предоставляют функцию отправки
, которая запускает ваши редукторы.
Вместо передачи функции dispatch
давайте передадим функцию update
, которая работает как setState
.
? Создание худшей версии Redux
Когда вы вызываете update, вы говорите, как именно должно измениться состояние inline. Это может быть или не быть рядом с другими аналогичными изменениями состояния.
При достаточно маленьком состоянии это действительно приятно и лаконично. Если бы у нас было 5 или более компонентов, изменяющих несколько свойств состояния, было бы трудно найти источник ошибок. ? ?
Даже не меняя redux, вы можете эмулировать этот паттерн. Действия диспетчеризации, которые выглядят как SET_COUNT
, намекают, что нам действительно просто нужен setState
.Это легко сделать.
Если мы создадим менее самоуверенное действие, такое как INCREMENT_BUTTON_CLICKED
, мы сможем использовать его во многих редукторах, и полезная нагрузка действия не будет слишком сильно варьироваться.
? Редукторы полезны не только для состояния.
Здесь вводится текущий URL, а на выходе — представление! Редукторы— отличный способ разместить решения. Если вы раньше работали с react-router-4, то приведенный выше код должен показаться вам довольно знакомым.
Благодаря компоненту
Теперь, если у кого-то есть вопрос: «Какими способами URL может изменять то, что отрисовывается», у него есть одно центральное место для поиска.
? Подводя итог
- Редукторы как шаблон существуют вне Redux и Javascript и просты в реализации. У них одна-единственная ответственность - принимать вход и выдавать результат.
- Редукторы Redux переводят события приложения в состояние. Для этого вам не нужен Redux, вы можете сделать это с локальным состоянием компонента.
- Редукторы упрощают организацию и поиск различных вариантов того, что может происходить в коде, и полезны по мере роста приложений.
Если у вас есть какие-либо вопросы или вы ищете индивидуального наставничества в React, не стесняйтесь писать мне в Твиттере @yurkaninryan в любое время!
Если вам нравится мой стиль письма, вот еще несколько моих статей.
reactjs - как обновить состояние с помощью reducer, когда мое состояние - это массив, а не объект
У меня проблема с возвратом нового состояния в моей функции редуктора. Мое состояние - это массив объектов. Каждый объект имеет две пары "ключ-значение" категория: '' и элементов: [{}, {}, {}] .
const initialState = [
{
категория: 'овощи',
Предметы: [
{
id: 1,
имя: 'морковь',
количество: 3,
единица измерения: 'pc',
},
{
id: 2,
название: 'картофель',
количество: 1,
единица измерения: 'кг',
},
{
id: 3,
название: 'брокколи',
количество: 2,
единица измерения: 'pc',
},
],
},
{
категория: 'фрукты',
Предметы: [
{
id: 4,
имя: 'апельсин',
количество: 4,
единица измерения: 'pc',
},
{
id: 5,
название: 'черника',
количество: 250,
единица измерения: 'г',
},
],
},
{
категория: 'напитки',
Предметы: [
{
id: 6,
название: "Кока-кола",
количество: 2,
единица: 'l',
},
{
id: 7,
название: 'Грейпфрутовый сок',
количество: 1,
единица: 'l',
},
{
id: 8,
название: 'Вода',
количество: 1,
единица: 'l',
},
],
},
{
категория: 'зерновые продукты',
Предметы: [
{
id: 9,
название: 'Зерновые',
количество: 2,
unit: 'pack',
},
{
id: 10,
название: 'Мюсли',
количество: 1,
единица измерения: 'кг',
},
],
},
];
Я хочу удалить элементы из массива элементов, а остальные оставить без изменений.Проблема в моей функции редуктора, и мой оператор switch возвращает неправильное значение:
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'REMOVE_ITEM':
состояние = [
state.map ((element) => element.items.filter ((item) => item.id! == action.payload.id)),
];
вернуть состояние;
дефолт:
вернуть состояние;
}
};
Я не прошу быстрого исправления, я был бы очень признателен только за подсказку.
Спасибо, ребята!
редукторов в JavaScript. Полное введение в JS-редукторы… | Надун Малинда | Июль, 2021 г.
Редуктор - это не что иное, как простая функция, которая принимает два аргумента и на основе этих двух аргументов возвращает новое значение состояния.
Редуктор примет состояние и действие, а затем вернет новое состояние. Bellow - это псевдофункция, которая представляет эту концепцию.
Это можно переписать следующим образом с помощью стрелочной функции JavaScript.
Обратите внимание, что даже несмотря на то, что я использовал « цвет » в качестве первого аргумента выше, это по-прежнему переменная состояния , и мы можем назвать ее как угодно. А также обратите внимание, что второй аргумент: « действие ». Это простой объект со свойством типа и необязательным свойством полезной нагрузки , другим объектом. Поскольку этот объект полезной нагрузки является необязательным, и для простоты этого первого примера я просто опущу его здесь и использую позже в этой статье.
На основе свойства типа в объекте действия редуктор может возвращать новое состояние условно.
Это прямое использование концепции редуктора, но в ваших приложениях чаще всего встречаются более сложные состояния, чем это. Очень часто внутри функций-редукторов используется оператор switch-case , а не оператор if-else . Если это переписать с использованием переключателя , , это будет выглядеть так: -
Тогда давайте рассмотрим немного сложную функцию редуктора с дополнительным свойством (объектом) полезной нагрузки в объекте действия .
Прежде чем погрузиться в саму функцию редуктора, мне нужно выделить пару моментов в приведенном выше разделе кода. Во-первых, в строке номер 2 я использовал уничтожение объекта JavaScript, чтобы извлечь свойства из объекта полезной нагрузки и привязать их к константе. Если вы не знакомы с этой концепцией, я рекомендую сначала пройти через нее.
Еще одна важная вещь заключается в том, что функции редуктора используются для возврата нового значения состояния на основе значения входящего состояния в функцию. Это означает, что мы никогда напрямую не изменяем состояние задач; скорее, функция reducer возвращает новый объект todos.Короче говоря, состояние, обрабатываемое функцией редуктора, неизменяемо.
Обратите внимание, что в строках 8 и 17 выше я использую оператор распространения JavaScript, чтобы изменить только часть согласованного задания, не касаясь остальной части этого задания. А также, используя метод карты массива , я всегда гарантирую, что возвращаю новый массив , используя входящий массив todos . Так мы обеспечиваем неизменность состояния, в нашем случае задач.
Итак, мы можем использовать нашу функцию todoReducer в нашем приложении, как показано ниже.Обратите внимание, как я определяю объект действия и его необязательное свойство полезной нагрузки. Полезная нагрузка Свойство (объект) состоит из минимального количества информации, которую наши функции-редукторы должны знать для изменения состояния.
После вызова todoReducer новый объект состояния todos будет выглядеть следующим образом: -
10 советов по улучшению архитектуры Redux | Эрик Эллиотт | JavaScript Scene
Когда я начал использовать React, Redux не было.Была только архитектура Flux и около десятка ее конкурирующих реализаций.
Теперь есть два явных победителя в области управления данными в React: Redux и MobX, причем последний даже не является реализацией Flux. Redux настолько прижился, что его больше не используют только для React. Вы можете найти реализации архитектуры Redux для других фреймворков, включая Angular 2. См., Например, ngrx: store.
Примечание: MobX - это круто, и я, вероятно, предпочел бы Redux для простых пользовательских интерфейсов, потому что он менее сложен и менее подробен.Тем не менее, есть некоторые важные функции Redux, которые MobX не предоставляет вам, и важно понимать, что это за функции, прежде чем вы решите, что подходит для вашего проекта.
Боковое примечание: Relay и Falcor - другие интересные решения для управления состоянием, но в отличие от Redux и MobX, они должны поддерживаться GraphQL и Falcor Server, соответственно, и все состояние Relay соответствует некоторым данным, сохраняемым на сервере. AFAIK, ни один из них не предлагает хорошей истории для управления переходным состоянием только на стороне клиента.Вы можете воспользоваться преимуществами обоих, смешав и сопоставив Relay или Falcor с Redux или MobX, различая состояние только для клиента и состояние, сохраняемое на сервере. Итог: на сегодняшний день нет явного единственного победителя в управлении государством на стороне клиента. Используйте подходящий инструмент для выполняемой работы.
Дэн Абрамов, создатель Redux, сделал несколько отличных курсов по этой теме:
Оба являются отличными пошаговыми руководствами, которые объясняют основы Redux, но вам также понадобится более высокий уровень понимания, чтобы получить максимальную отдачу от Redux.
Ниже приведены советы, которые помогут вам создавать лучшие приложения Redux.
Есть несколько важных целей для Redux, о которых вы должны помнить:
- Детерминированное представление визуализации
- Детерминированное воспроизведение состояния
Детерминизм важен для тестируемости приложений, а также для диагностики и исправления ошибок. Если представления и состояние вашего приложения недетерминированы, невозможно узнать, будут ли представления и состояние всегда действительными.Можно даже сказать, что недетерминизм сам по себе является ошибкой.
Но некоторые вещи по своей сути недетерминированы. Такие вещи, как время ввода пользователя и сетевой ввод-вывод. Итак, как мы можем узнать, действительно ли наш код работает? Легко: изоляция.
Основная цель Redux - изолировать управление состоянием от побочных эффектов ввода-вывода, таких как рендеринг представления или работа с сетью. Когда побочные эффекты изолированы, код становится намного проще. Гораздо проще понять и протестировать бизнес-логику, если она не связана с сетевыми запросами и обновлениями DOM.
Когда рендеринг вашего представления изолирован от сетевого ввода-вывода и обновлений состояния, вы можете добиться детерминированного рендеринга представления, что означает: при одном и том же состоянии представление всегда будет отображать один и тот же вывод. Это исключает возможность таких проблем, как условия гонки из-за асинхронного материала, случайным образом уничтожающего части вашего представления или искажающие части вашего состояния, когда ваше представление находится в процессе рендеринга.
Когда новичок думает о создании представления, он может подумать: «Этот бит требует пользовательской модели, поэтому я запускаю асинхронный запрос, чтобы получить его, и когда это обещание будет выполнено, я обновлю пользовательский компонент, указав его имя. .В этом месте требуются задачи, поэтому мы их получим, а когда обещание выполнится, мы переберем их в цикле и выведем на экран ».
При таком подходе есть несколько серьезных проблем:
- У вас никогда не бывает всех данных, необходимых для визуализации полного представления в любой момент. Фактически вы не начинаете получать данные, пока компонент не начнет делать свое дело.
- Различные задачи выборки могут приходить в разное время, слегка изменяя порядок, в котором что-то происходит в последовательности рендеринга вида.Чтобы по-настоящему понять последовательность рендеринга, вы должны знать то, что вы не можете предсказать: продолжительность каждого асинхронного запроса. Популярная викторина: что в приведенном выше сценарии отображается в первую очередь, пользовательский компонент или задачи? Ответ: Это гонка!
- Иногда прослушиватели событий изменяют состояние просмотра, что может вызвать другой рендеринг, что еще больше усложняет последовательность.
Ключевая проблема с хранением ваших данных в состоянии представления и предоставлением слушателям асинхронных событий доступа для изменения этого состояния представления заключается в следующем:
«Недетерминизм = параллельная обработка + общее состояние»
~ Мартин Одерски (дизайнер Scala)
Объединение задач выборки данных, манипулирования данными и визуализации представлений - рецепт для спагетти, путешествующих во времени.
Я знаю, что это звучит круто в научно-фантастических фильмах категории «B», но поверьте мне, спагетти с путешествием во времени - это худший вид дегустации!
Архитектура потока обеспечивает строгое разделение и последовательность, которая подчиняется этим правилам каждый раз:
- Сначала мы переходим в известное фиксированное состояние…
- Затем мы визуализируем представление. Ничто не может снова изменить состояние этого цикла рендеринга.
- При одинаковом состоянии представление всегда будет отображаться одинаково.
- Слушатели событий прослушивают пользовательский ввод и обработчики сетевых запросов. Когда они их получают, действия отправляются в магазин.
- При отправке действия состояние обновляется до нового известного состояния, и последовательность повторяется. Только отправленные действия могут касаться состояния.
Вкратце, это Flux: Архитектура одностороннего потока данных для вашего пользовательского интерфейса:
Архитектура FluxВ архитектуре Flux представление слушает ввод пользователя, переводит его в объекты действия, которые отправляются в хранилище.Магазин обновляет состояние приложения и уведомляет представление о необходимости повторного рендеринга. Конечно, представление редко является единственным источником ввода и событий, но это не проблема. Дополнительные прослушиватели событий отправляют объекты действий, как и представление:
Важно отметить, что обновления состояния в Flux являются транзакционными. Вместо простого вызова метода обновления состояния или непосредственного управления значением в хранилище отправляются объекты действия. Объект действия - это запись транзакции. Вы можете думать об этом как о банковской транзакции - записи об изменении, которое необходимо внести.Когда вы делаете депозит в свой банк, ваш баланс, оставшийся 5 минут назад, не стирается. Вместо этого в историю транзакций добавляется новый баланс. Объекты действий добавляют историю транзакций в состояние вашего приложения.
Объекты действий выглядят следующим образом:
Объекты действий дают вам возможность вести текущий журнал всех транзакций состояния. Этот журнал можно использовать для детерминированного воспроизведения состояния, что означает:
При одинаковом начальном состоянии и одинаковых транзакциях в одном порядке в результате вы всегда получаете одно и то же состояние.
Это имеет важные последствия:
- Простая возможность тестирования
- Простая отмена / повтор
- Отладка путешествия во времени
- Долговечность - Даже если состояние будет стерто, если у вас есть запись каждой транзакции, вы можете воспроизвести ее.
Кто не хочет владеть пространством и временем? Состояние транзакции дает вам сверхспособности для путешествий во времени:
Ползунок истории инструментов разработчика ReduxЕсли ваш рабочий процесс пользовательского интерфейса прост, все это может быть излишним.Если вы играете в крестики-нолики, вам действительно нужно отменить / повторить? Игры редко длятся больше минуты. Если пользователь ошибается, вы можете просто перезагрузить игру и позволить им начать все заново.
Если:
- Рабочие процессы пользователей просты
- Пользователи не взаимодействуют между собой
- Вам не нужно управлять событиями на стороне сервера (SSE) или веб-сокетами
- Вы получаете данные из одного источника данных для каждого представления
Может случиться так, что последовательность событий в приложении, вероятно, настолько проста, что преимущества транзакционного состояния не стоят дополнительных усилий.
Возможно, вам не нужно изменять приложение Fluxify. Для подобных приложений есть гораздо более простое решение. Проверьте MobX.
Однако по мере того, как растет сложность вашего приложения, по мере того, как растет сложность управления состоянием представления, вместе с ним растет и ценность состояния транзакции, и MobX не обеспечивает управление состоянием транзакции из коробки.
Если:
- Пользовательские рабочие процессы сложны
- В вашем приложении большое количество пользовательских рабочих процессов (учитывайте как обычных пользователей, так и администраторов)
- Пользователи могут сотрудничать
- Вы используете веб-сокеты или SSE
- Вы загрузка данных с нескольких конечных точек для построения единого представления
Вы можете получить достаточно преимуществ от модели состояния транзакции, чтобы она окупилась.Redux может вам подойти.
При чем здесь веб-сокеты и SSE? По мере добавления дополнительных источников асинхронного ввода-вывода становится все труднее понять, что происходит в приложении с неопределенным управлением состоянием. Детерминированное состояние и запись транзакций состояния радикально упрощают подобные приложения.
На мой взгляд, большинство крупных продуктов SaaS включают как минимум несколько сложных рабочих процессов пользовательского интерфейса и должны использовать управление состоянием транзакций. Большинство небольших служебных приложений и простых прототипов не должны.Используйте подходящий инструмент для работы.
Redux = Flux + Функциональное программирование
Flux предписывает односторонний поток данных и состояние транзакции с объектами действий, но ничего не говорит о том, как обрабатывать объекты действий. Здесь на помощь приходит Redux.
Основным строительным блоком управления состоянием Redux является функция редуктора. Что такое функция редуктора?
В функциональном программировании общая утилита `reduce ()` или `fold ()` используется для применения функции редуктора к каждому значению в списке значений с целью накопления единственного выходного значения.Вот пример суммирующего редуктора, примененного к массиву JavaScript с помощью `Array.prototype.reduce ()`:
Взаимодействовать с ним на CodePenВместо работы с массивами Redux применяет редукторы к потоку объектов действий. Помните, что объект действия выглядит так:
Давайте превратим суммирующий редуктор выше в редуктор в стиле Redux:
Теперь мы можем применить его к некоторым тестовым действиям:
Чтобы добиться детерминированного воспроизведения состояния, редукторы должны быть чистыми. функции.Без исключений. Чистая функция:
- При одном и том же вводе всегда возвращает один и тот же вывод.
- Не имеет побочных эффектов.
Важно, что в JavaScript все непримитивные объекты передаются в функции как ссылки. Другими словами, если вы передаете объект, а затем напрямую изменяете свойство этого объекта, объект также изменяется вне функции. Это побочный эффект. Вы не можете понять полное значение вызова функции, не зная также полную историю переданного вами объекта.Плохо.
Редукторы должны вместо этого возвращать новый объект. Вы можете сделать это, например, с помощью `Object.assign ({}, state, {thingToChange})` .
Параметры массива также являются справочными. Вы не можете просто добавить `.push ()` новых элементов в массив в редукторе, потому что `.push ()` - это операция изменения. Аналогично, `.pop ()` , `.shift ()` , `.unshift ()`, `.reverse ()`, `.splice ()`, и любой другой метод мутатора .
Если вы хотите быть в безопасности с массивами, вам нужно ограничить операции, которые вы выполняете с состоянием, безопасными методами доступа. Вместо `.push ()` используйте `.concat ()`.
Взгляните на случай `ADD_CHAT` в этом редукторе чата:
Как видите, новый объект создается с помощью ` Object.assign () `, и мы добавляем к массиву с помощью `.concat ()` вместо `.push ()` .
Лично я не люблю беспокоиться о случайном изменении своего состояния, поэтому в последнее время я экспериментировал с использованием API неизменяемых данных с Redux.Если мое состояние - неизменяемый объект, мне даже не нужно смотреть в код, чтобы знать, что объект не был случайно изменен. Я пришел к такому выводу после работы в команде и обнаружения ошибок из-за случайных мутаций состояний.
Чистые функции - это гораздо больше. Если вы собираетесь использовать Redux для производственных приложений, вам действительно нужно хорошо понимать, что такое чистые функции, и о других вещах, о которых нужно помнить (например, о времени, регистрации и случайных числах).Для получения дополнительной информации см. «Интервью по JavaScript: что такое чистая функция?».
Все состояние в вашем приложении должно иметь единый источник истины. Это означает, что состояние хранится в одном месте, а в любом другом месте, где это состояние необходимо, доступ к состоянию должен осуществляться посредством ссылки на его единственный источник истины.
Иметь разные источники истины для разных вещей - это нормально. Например, URL-адрес может быть единственным источником истины для пути запроса пользователя и параметров URL-адреса. Возможно, в вашем приложении есть служба конфигурации, которая является единственным источником достоверных данных для ваших URL-адресов API.Хорошо. Однако…
Когда вы сохраняете какое-либо состояние в хранилище Redux, любой доступ к этому состоянию должен осуществляться через Redux. Несоблюдение этого принципа может привести к устаревшим данным или к видам ошибок мутации общего состояния, для решения которых были изобретены Flux и Redux.
Другими словами, без единого источника истинности вы потенциально потеряете:
- Детерминированный рендеринг
- Детерминированное воспроизведение состояния
- Простая отмена / повтор
- Отладка перемещения во времени
- Простая тестируемость
Либо Redux, либо не переупаковывайте свое состояние.Если вы сделаете это наполовину, вы можете лишиться всех преимуществ Redux.
Мне нравится следить за тем, чтобы действия можно было легко отследить до редуктора, который их использует, когда вы просматриваете историю действий. Если все ваши действия имеют короткие общие имена, такие как `CHANGE_MESSAGE`, , становится труднее понять, что происходит в вашем приложении. Однако, если типы действий имеют более описательные имена, такие как `CHAT :: CHANGE_MESSAGE` , очевидно, что происходит гораздо более ясно.
Кроме того, если вы сделаете опечатку и отправите неопределенную константу действия, приложение выдаст ошибку, чтобы предупредить вас об ошибке.Если вы сделаете опечатку со строкой типа действия, действие автоматически завершится ошибкой.
Сохранение всех типов действий для редуктора, собранных в одном месте в верхней части файла, также может помочь вам:
- Сохранение согласованности имен
- Быстрое понимание API редуктора
- Посмотрите, что изменилось в запросах на вытягивание
Когда Я говорю людям, что они не могут сгенерировать идентификаторы или получить текущее время в редукторе, и у меня смешные взгляды. Если вы сейчас подозрительно смотрите на экран, будьте уверены: вы не одиноки.
Итак, где же хорошее место для обработки такой нечистой логики, не повторяя ее везде, где вам нужно использовать действие? В создателе действий.
Создатели действий имеют и другие преимущества:
- Сохраняйте константы типов действий инкапсулированными в вашем файле-редукторе, чтобы вам не приходилось импортировать их куда-либо еще.
- Сделайте некоторые расчеты по входам перед отправкой действия.
- Уменьшить шаблон
Давайте воспользуемся создателем действия для создания объекта действия ADD_CHAT :
Как вы можете видеть выше, мы используем cuid для генерации случайных идентификаторов для каждого сообщения чата и Date.now () ` для создания отметки времени. Обе эти операции являются нечистыми, и их небезопасно запускать в редукторе, но вполне нормально запускать их в создателях действий.
Уменьшить шаблон с помощью Action Creators
Некоторые люди думают, что использование Action Creators добавляет шаблон в проект. Напротив, вы скоро увидите, как я использую их для значительного сокращения шаблонов в моих редукторах.
Совет. Если вы храните константы, редуктор и создатели действий в одном файле, вы уменьшите количество шаблонов, требуемых при импорте их из разных мест.
Представьте, что мы хотим добавить возможность пользователю чата настраивать свое имя пользователя и статус доступности. Мы могли бы добавить к редуктору пару обработчиков типов действий, например:
Для более крупных редукторов это могло бы вырасти до большого количества шаблонов. Многие редукторы, которые я построил, могут быть намного сложнее, чем это, с большим количеством избыточного кода. Что, если бы мы могли свернуть все простые действия по изменению свойств вместе?
Оказывается, это просто:
Даже с дополнительным интервалом и дополнительным комментарием эта версия короче - и это только два случая.Экономия действительно может быть увеличена.
Разве выключатель… не опасен? Я вижу провал!
Вы, возможно, где-то читали, что следует избегать операторов `switch` , в частности, чтобы избежать случайного провала и потому, что список случаев может стать раздутым. Возможно, вы слышали, что никогда не следует использовать провалы намеренно, потому что очень сложно поймать случайные ошибки, которые могут провалиться. Это хороший совет, но давайте хорошенько подумаем об опасностях, о которых я упоминал выше:
- Редукторы можно компоновать, поэтому раздувание корпуса не проблема.Если ваш список случаев становится слишком большим, отломайте части и переместите их в отдельные редукторы.
- Каждое тело чемодана возвращается, поэтому случайное падение не должно произойти. Ни у одного из сгруппированных случаев падения не должно быть других тел, кроме того, которое выполняет ловлю.
Redux использует `switch..case` well. Я официально меняю свой совет по этому поводу. Пока вы следуете простым правилам, приведенным выше (держите переключатели маленькими и сфокусированными, и возвращайтесь из каждого случая с его собственным телом), операторы `switch` подойдут.
Вы могли заметить, что эта версия требует другой полезной нагрузки. Вот где появляются ваши создатели действий:
Как видите, эти создатели действий осуществляют перевод между аргументами и формой состояния. Но это еще не все, что они делают ...
Если вы используете Tern.js с плагином редактора (доступным для популярных редакторов, таких как Sublime Text и Atom), он прочитает эти назначения ES6 по умолчанию и определит требуемый интерфейс вашего Создатели действий, поэтому, когда вы вызываете их, вы можете получить intellisense и автозаполнение.Это снимает когнитивную нагрузку с разработчиков, поскольку им не нужно запоминать требуемый тип полезной нагрузки или проверять исходный код, если они забудут.
Если вы не используете подключаемый модуль вывода типа, такой как Tern, TypeScript или Flow, вам следует его использовать.
Примечание: я предпочитаю полагаться на логический вывод, предоставляемый назначениями по умолчанию, видимыми в сигнатуре функции, а не на аннотации типов, потому что:
- Вам не нужно использовать Flow или TypeScript, чтобы заставить его работать: вместо этого вы используете стандартные JavaScript.
- Если вы используете TypeScript или Flow, аннотации избыточны с назначениями по умолчанию, потому что и TypeScript, и Flow определяют тип из назначения по умолчанию.
- Я нахожу его более читаемым, когда синтаксический шум меньше.
- Вы получаете настройки по умолчанию, что означает, что даже если вы не останавливаете сборку CI из-за ошибок типа (вы удивитесь, многие проекты этого не делают), у вас никогда не будет случайного `undefined` параметр, скрывающийся в вашем коде.
Представьте, что вы создаете самое сложное приложение для чата в истории приложений для чата.Вы написали 500 тыс. Строк кода, и ТОГДА команда разработчиков предъявляет вам новые требования к функциям, которые заставят вас изменить структуру данных вашего состояния.
Не нужно паниковать. Вы были достаточно умны, чтобы отделить остальную часть приложения от формы вашего состояния с помощью селекторов. Пуля: увернулась.
Почти для каждого редуктора, который я пишу, я создаю селектор, который просто экспортирует все переменные, которые мне нужны для создания представления. Давайте посмотрим, как это может выглядеть для нашего простого редуктора чата:
export const getViewState = state => state;
Да, я знаю.Это так просто, что даже не стоит думать. Вы можете подумать, что я сошел с ума, но помните ту пулю, от которой мы уклонялись раньше? Что, если бы мы хотели добавить какое-то вычисленное состояние, например полный список всех пользователей, которые общались в чате во время этого сеанса? Назовем его "RecentActiveUsers".
Эта информация уже хранится в нашем текущем состоянии, но не так, чтобы ее было легко получить. Давайте возьмем его в `getViewState ()` :
Если вы поместите все свое вычисленное состояние в селекторы, вы:
- Уменьшите сложность редукторов и компонентов
- Отделите остальную часть вашего приложения от вашего state shape
- Соблюдайте принцип единого источника истины, даже в пределах вашего редуктора
Во многих исследованиях сравнивали методологии «сначала тестирование» с методологиями «тестирование после», а также с отсутствием тестов вообще.Результаты ясны и впечатляющи: большинство исследований показывают снижение количества ошибок при доставке на 40–80% в результате написания тестов перед реализацией функций.
TDD может эффективно сократить вдвое количество ошибок при доставке, и есть множество доказательств, подтверждающих это утверждение.
При написании примеров в этой статье я начал их все с юнит-тестов.
Чтобы избежать нестабильных тестов, я создал следующие фабрики, которые использовал для выработки ожиданий:
Обратите внимание, что обе они предоставляют значения по умолчанию, что означает, что я могу переопределять свойства по отдельности, чтобы создавать только те данные, которые меня интересуют для любого конкретного теста.
Вот как я их использовал:
Примечание. Я использую ленту для модульных тестов из-за ее простоты. У меня также есть 2–3-летний опыт работы с Mocha и Jasmine, а также разный опыт работы с множеством других фреймворков. Вы должны уметь адаптировать эти принципы к любой выбранной вами структуре.
Обратите внимание на стиль, который я разработал для описания вложенных тестов. Вероятно, из-за моего опыта работы с Jasmine и Mocha, мне нравится начинать с описания компонента, который я тестирую, во внешнем блоке, а затем во внутренних блоках, описывать то, что я передаю компоненту.Внутри я делаю простые утверждения эквивалентности, которые вы можете сделать с помощью функций `deepEqual ()` или `toEqual ()` вашей библиотеки тестирования.
Как видите, я использую изолированные тестовое состояние и фабричные функции вместо таких утилит, как `beforeEach ()` и `afterEach ()` , чего я избегаю, потому что они могут побудить неопытных разработчиков использовать общее состояние в набор тестов (это плохо).
Как вы, наверное, догадались, у меня есть три разных вида тестов для каждого редуктора:
- Тесты прямого редуктора, пример которых вы только что видели.По сути, они проверяют, что редуктор создает ожидаемое состояние по умолчанию.
- Тесты создателя действия, которые проверяют каждый создатель действия, применяя редуктор к действию с использованием некоторого предопределенного состояния в качестве отправной точки.
- Тесты селекторов, которые проверяют селекторы, чтобы убедиться, что все ожидаемые свойства присутствуют, включая вычисленные свойства с ожидаемыми значениями.
Вы уже видели тест редуктора. Давайте посмотрим на другие примеры.
Тесты Action Creator
Этот пример интересен по нескольким причинам.Создатель действий `addChat ()` не чист. Это означает, что, если вы не передадите переопределения значений, вы не сможете сделать определенные ожидания для всех созданных свойств. Чтобы справиться с этим, мы использовали конвейер, который я иногда использую, чтобы избежать создания дополнительных переменных, которые мне действительно не нужны. Я использовал его, чтобы игнорировать сгенерированные значения. Мы по-прежнему следим за их существованием, но нам все равно, каковы ценности. Обратите внимание, что я даже не проверяю тип. Мы полагаем, что выведение типов и значения по умолчанию позаботятся об этом.
Канал - это функциональная утилита, которая позволяет передавать некоторое входное значение через серию функций, каждая из которых принимает выходные данные предыдущей функции и тем или иным образом их преобразует. Я использую lodash pipe из lodash / fp / pipe, который является псевдонимом для lodash / flow. Интересно, что сам `pipe ()` может быть создан с помощью функции редуктора:
Я обычно часто использую `pipe ()` в файлах редуктора, а также для упрощения переходов между состояниями. Все переходы между состояниями в конечном итоге представляют собой потоки данных, перемещающиеся от одного представления данных к другому.Вот в чем хорош `pipe ()` .
Обратите внимание, что создатель действий позволяет нам также переопределить все значения по умолчанию, поэтому мы можем передавать определенные идентификаторы и временные метки и проверять определенные значения.
Тесты селектора
Наконец, мы тестируем селекторы состояний и убеждаемся, что вычисленные значения верны и все в порядке:
Обратите внимание, что в этом тесте мы использовали `Array.prototype.reduce ( ) ` для сокращения нескольких примеров ` addChat () ` действий.Одна из замечательных особенностей редукторов Redux заключается в том, что они представляют собой обычные функции редуктора, а это значит, что вы можете делать с ними все, что вы делаете с любой другой функцией редуктора.
Наше «ожидаемое» значение проверяет, что все наши объекты чата находятся в журнале и правильно ли указаны недавно активные пользователи.
Больше особо нечего сказать об этом.
Если вы правильно используете Redux, вы получите основные преимущества:
- Устранение ошибок временной зависимости
- Включить детерминированный рендеринг представления
- Включить детерминированное воспроизведение состояния
- Включить функции простой отмены / повтора
- Упростить отладку
- Станьте путешественником во времени
Но чтобы все это работало, вы должны помнить некоторые правила:
- Редукторы должны быть чистыми функциями
- Редукторы должны быть единственным источником истины для своего состояния
- Состояние редуктора всегда должно быть сериализуемый
- Состояние редуктора не должно содержать функций
Также имейте в виду:
- Некоторым приложениям не нужен Redux
- Используйте константы для типов действий
- Используйте создатели действий, чтобы отделить логику действий от вызывающих диспетчеров
- Используйте ES6 значения по умолчанию для сигнатур с самоописанием
- Использовать селекторы для вычисляемого состояния и деко pling
- Всегда используйте TDD!
Наслаждайтесь!
.