Остин Малерба
Руководство по местному и глобальному государственному управлению через USESTATE
С момента введения API реагирования API я видел много обсуждений о Уместите , Успенсер и когда использовать один над другим. Из этих разговоров можно было бы заключить, что Уместите лучше всего подходит для простого состояния с простой логикой обновления и что Успенсер лучше всего для сложных форм состояний со сложной логикой обновления.
Я здесь, чтобы убедить вас, что При завернении в 4 строку пользовательского крючка, утилизация может быть так же мощным, как, если не более мощный, чем у useruger при управлении сложным состоянием.
Я не люблю редукторов. Я пытался использовать их, но я всегда в конечном итоге мигрируя. Что-то просто чувствует себя неправильно распределить действия, чтобы вызвать бизнес-логику, когда я могу вместо этого сделать это, вызывая функцию с аргументами.
И тогда есть тот факт, что вместо того, чтобы инкапсулировать свою бизнес-логику в функции, я должен скорректировать все это в одну гигантскую функцию, разбиваемую кучами переключателей? Я пробовал библиотеки, такие как Redux-действия Чтобы облегчить эту проблему, но я все еще не мог справиться с этим. Моя не нравится для редукторов мотивировала меня искать лучшее решение.
Давайте рассмотрим несколько распространенных причин, почему люди выбирают Успенсер над Уместите :
- Таким образом, бизнес-логика может быть централизована в редукторе, а не разбросана о компоненте
- Редукторы являются чистыми функциями, которые легко проверить в изоляции реагирования
- Редукторы позволяют употреблять части состояния, которые зависят друг от друга, которые будут обновляться как предразводится (тогда как не может быть несколько
useState
Если какая-либо из этих пули запутается, я бы порекомендовал взглянуть на это Статья Отказ На протяжении всего этого руководства я вернусь к этим пунктам как три преимущества редукторов.
Шаг первый: построить пример
Во-первых, я собираюсь показать вам пример, который демонстрирует преимущества редукторов, которые я упомянул выше, и тогда я собираюсь показать вам, как вы можете реализовать ту же функциональность через Уместите не жертвуя любым из преимуществ Успенсер решение.
Морящий счетчик
Чтобы проиллюстрировать плюсы/минусы Уместите против упред Я собираюсь реализовать простой счетчик с поворотом. Счетчик может быть увеличен, но также может быть заморожен. Если в замороженном состоянии, увеличивая счетчик, ничего не сделает.
Как видите, я внедрил наш счетчик выше один раз с Уместите И однажды с Успенсер Отказ Тем не менее, Statecounterv1 имеет некоторые проблемы. На самом деле, это даже не работает должным образом.
Мы ожидаем, что Statecounterv1 Должен рендер потому что мы увеличиваем счетчик один раз, то замораживаем счетчик, а затем мы снова увеличиваем. Но на самом деле Это делает
второй Вызов приращения не имеет в соотв ess до Новая ценность замороженного. Это IL Люстраты Бенес T # 3 из Успенцер над тельцемией. Также очевидно, что в Statecounterv1 Наша логика для увеличения пристег находит в сам компонент, но в Reewarderter Логика относится к Сортирью (Пособие № 1).
И, наконец, мы видим, что для проверки логики подсчета в Statecounterv1. Мы должны были бы сделать это, тогда как проверить логику в Сортирью , мы могли бы сделать это, не приходив на визуализацию компонента. Мы могли бы проверить его, просто вызывая его с состоянием и действием и обеспечением его вывода правильного следующего состояния (выгода № 2).
Шаг второй: Свернувшееся состояние
В нашем примере у нас есть государственный переход, увеличение , что обновления Считать Но зависит от другой часть государства, замороженные Отказ В таких случаях, как это, я считаю его лучше всего укрепить государство. Теоретически мы всегда могли бы иметь максимум одного Уместите Крючок на компонент и до сих пор добиться любой функциональности, которую мы хотим. Но это совершенно в порядке Уместите несколько раз Пока запасы государства не зависят друг от друга при обновлении Отказ С этим сказанным, давайте посмотрим, как уплотнительное состояние может вернуть нам преимущество # 3 редукторов.
Теперь Updater передал SetState В нашем увеличение Функция самодостаточная. Это больше не нужно добраться до замороженные Через закрытие, чтобы определить, как производить следующее состояние. Вместо этого Превзойти Содержит все государства, необходимое для выполнения логики обновления.
Потому что это самодостаточное, у нас больше нет необходимости объявлять его в визуализации времени, мы можем вместо этого поднять его из компонента.
Когда мы поднимаем декларации штата-обновления за пределами нашего компонента, не только улучшаем производительность, но мы не предотвращаем случайно в зависимости от переменных через закрытие, как мы сделали в Statecounterv1. . Этот шаблон немного помимо точки этой статьи, но я подумал, что я все равно упомяну об этом.
Шаг три: Извлечение бизнес-логики
На данный момент Statecounterv2 все еще раздувается с счетчиком логики. Но никаких забот, все, что нам нужно сделать, это извлечь всю нашу счетчик бизнес-логики в пользовательский крючок. Давайте назовем это Usecounterapi. .
Сейчас Statecounterv3 выглядит хорошо. Я бы поспорил, что это выглядит даже лучше, чем Reewarderter Отказ Не говоря уже о том, чтобы этот рефакторинг был простым, потому что все это действительно взяло, было копией/пасты нашей счетчики логики на пользовательский крючок. Но вот где вещи становится сложным.
Иногда может быть трудно, как разработчики, чтобы определить, где принадлежит логику. Наши мозги неустойчивы, и есть несколько дней, когда мне не произойдет, чтобы извлечь эту логику из компонента в пользовательский встречный крючок. Вот почему у нас разработчики нужны самые интересные интерфейсы, чтобы направлять нас в правильном направлении.
Шаг четвертый: Создание руководства
Если бы нам пришлось описать Usecounterapi Устно, мы, наверное, говорили,
Здесь внутри ложись наша первая подсказка. Это создает и возвращает API Отказ Таким образом, это завод API. Более конкретно, это Счетчик API завод.
Но нам нравится абстрактные вещи, поэтому следующий вопрос, как мы можем сделать Общий API завод? Ну, давайте удалим «счетчик» из Usecounterapi. . Теперь мы остались с useapi Отказ Удивительно, теперь у нас есть наш общий завод API. Но откуда уходит наша деловая логика?
Давайте подумаем о том, как Успенсер работает.
const [state, dispatch] = useReducer(reducer, initialArg, init);
Первый аргумент Успенсер это редуктор, а второй аргумент является начальным состоянием. Помните, что редуктор содержит бизнес-логику. Попробуем имитировать этот интерфейс.
const api = useApi(someApiFactoryFunction, initialArg);
Хорошо, похоже, что мы приближаемся к решению. Но теперь мы должны выяснить, что чертовски Сомеапакторияфункция должен делать.
Ну, мы знаем, что это должно содержать деловую логику И мы знаем, что это не знает о реакции, чтобы мы могли проверить его без необходимости рендеринга компонента. То, что мы также знаем, что Сомеапакторияфункция не может содержать Уместите Призыв, потому что тогда это будет знать о реагированных вещах. Но это, безусловно, нужно Государство и setstate. . Так что нам придется вводить штат и SetState какой-то другой путь. Итак, как мы снова вводим вещи в функции? О да, параметры. Привязывая эту мысль, мы в конечном итоге, мы в конечном итоге следующие.
И там это. useapi. Наша волшебная 4-х строчная индивидуальная крючка, которая показывает истинную силу Уместите Отказ Функции завода API предоставляют нам текущий Государство и а SetState Обратный вызов и давайте вызовите API из них. Давайте подумаем о том, какие преимущества мы только что введены с этим простым изменением контракта.
противоположность не знает об реакции, что означает, что теперь мы можем проверить это просто, проходя мимо Государство Объект и SetState Перезвоните (Редукторная выгода № 2 достигнута).
useapi ожидает завод API, что означает, что мы говорим разработчику они нужно Для записи фабрики API функционирует с подписью ({State, SetState}) => API. Это значит, даже в мои дни, когда мой мозг борется, чтобы узнать, что кластер логики может быть отказобновлен в государственную API, у меня есть этот хороший Литт le пользоваться Функция API, побуждая меня бросить всю мою государственную бизнес-логику в централизованное место.
Шаг пять: Оптимизация
Как это стоит, useapi не так эффективно, как могло бы быть. Любой компонент, который потребляет useapi вызовут useapi на каждом рендере, что означает Apifactory также будет вызываться на каждом визуализации. Не нужно вызывать Apifactory на каждом рендере, а скорее только когда Государство изменился. Мы можем оптимизировать useapi Воме в память о исполнении Apifactory Отказ
Тестирование API завод
Теперь, когда мы реализовали наши useapi Крюк, давайте посмотрим на то, как мы проверим завод API.
Это достаточно просто, чтобы создать обертку вокруг нашего противоположность что имитирует поведение Государство / SetState Отказ С этой функцией помощника мы можем проверить нашу противоположность очень естественным образом.
useapi vs userucer.
Давайте теперь сравним эти два решения.
Логическая инкапсуляция
В обоих растворах логика для обновления состояния централизована, что позволяет легко рассуждать, отладки и тестирование. Однако редукторы обеспечивают только механизм Обновление Состояние, они не предоставляют механизм Восстановить штат. Вместо этого следует писать селекторы и применить их вниз по течению от редуктора. Что хорошее о нашем useapi Решение заключается в том, что он инкапсулирует не только логику для обновления состояния, но и логика для Восстановить штат ?.
Обновление состояния
Обновить состояние с помощью Успенсер Нам нужно отправлять действия. Обновить состояние с помощью useapi. Нам нужно вызывать методы обновлений. Потенциальное преимущество редукторов в этом сценарии заключается в том, что несколько редукторов могут слушать то же действие. Однако это также поставляется с недостатком: поток выполнения не интуитивно, как только действие будет отправлено. Если мне нужно несколько, разбросываемые кусочки состояния, которые должны быть обновлены сразу, я бы скорее сделаю это явно с несколькими вызовами метода API на спине к спине к спину, чем через единое рассылаемое действие, которое транслируется для всех редукторов.
Представление
Одна приятная вещь о редукторах состоит в том, что через композицию редуктора несколько редукторов могут слушать одному отправленному действию, что означает, что у вас могут быть многие части изменения состояния всего за один рендер. Я не придумал решение для заводской композиции API (хотя это, безусловно, возможно). На данный момент мое решение состоит в том, чтобы вызвать государственные рентабелы обратно, когда это необходимо, чтобы привести к большему количеству рендеров, чем подход редуктора.
Котельная
Решения на основе редукторов, как известно, Boilerplate-Y (особенно при работе с redux). Декларации типа Действия занимают некоторые дополнительные пространственные и диспетчеризирующие действия, как правило, немного более многогосударственным, чем просто вызывающие функцию с аргументами. По этим причинам скажу useapi имеет небольшой край на Успенсер С точки зрения кода котельной.
Жилье
И редукторы, и API-фабрики легко проверить.
Дальнейшее изучение усеапо
Давайте посмотрим на некоторые другие классные вещи, которые мы можем сделать с useapi Отказ
Я занял время для реализации классики Пример списка redux todo через useapi Отказ Вот как Тодосапифакты Выглядит в реализацию aseapi.
Одна грубая вещь, которую вы, возможно, заметили в коде выше, – это повторение следующей котельной.
setState(prevState => ({ ...prevState, /* … */});Предполагая наше Государство это объект и потому что SetState не поддерживает Мелкое сливание , нам нужно сделать это, чтобы убедиться, что мы сохранили любое состояние, с которым мы не работаем в настоящее время.
Мы можем уменьшить часть этой котельной и получить другие прохладные преимущества из библиотеки под названием Иммер Отказ Immer – это библиотека неподумности, которая позволяет писать неизменный код во мнениях.
Как видите, Immer помогает нам удалить некоторые из этих раздражающих кодов котел, необходимый при написании неизменных обновлений. Но будьте осторожны, удобство иммерства также является его пяткой ACHILLES. Разработчик, который введен в концепцию неизменности через Immer, может не полностью понять последствия мутаций.
Но подождите секунду, useapi только предоставляет государству локально , но Список дел Пример Использует Redux для обеспечения глобальный Государственное решение.
Глобальные магазины с API-фабриками
Давайте посмотрим, как мы можем создавать глобальные магазины от фабрики API.
Неплохо вообще, верно? Контекст делает глобальное состояние Super легко в реакции. Поэтому теперь у нас есть глобальное государственное управленческое решение для использования с фабриками API.
Ниже приведен рабочие фабрики API Factory ToDo.
Заключение
Чтобы завернуть его, эта статья содержит три функции, которые вы можете найти полезными.
Эти функции предоставляют полезные абстракции для местного и глобального управления государством, работающим на Уместите Отказ
Не поймите меня неправильно, редукторы поставляются с большим количеством льгот, но я просто не могу отдохнуть легко с интерфейсом, который они предлагают. Оба useapi и Успенсер Предложите жизнеспособным решениям комплексного государственного управления. Это действительно вопрос предпочтений.
Одним из полезных на выносных каналах является то, что библиотеки не должны выполнять сложную логику, чтобы быть полезными. Многие из библиотек значений и рамок не должны делать с логикой, которые они выполняют, а скорее руководство, которое они дают разработчику. Хорошие библиотеки/рамки заставляют разработчику следовать известным узорам через явные и достоверные интерфейсы. useapi. Очень мало вычисляется, но поощряет разработчик поставить свою государственную бизнес-логику в централизованном месте, все то, избегая загрязнения компонентов.
Оригинал: “https://www.freecodecamp.org/news/why-you-should-choose-usestate-instead-of-usereducer-ffc80057f815/”