Я новичок в React / Redux. Я использую промежуточное ПО fetch api в приложении Redux для обработки API. Это ( redux-api-middleware ). Я думаю, что это хороший способ обрабатывать действия async api. Но я нахожу такие случаи, которые не могу разрешить самостоятельно.
Как говорится на домашней странице ( жизненный цикл ), жизненный цикл API выборки начинается с отправки действия CALL_API и заканчивается отправкой действия FSA.
Итак, мой первый случай показывает / скрывает предварительный загрузчик при получении API. Промежуточное ПО отправит действие FSA в начале и отправит действие FSA в конце. Оба действия принимаются редукторами, которые должны выполнять только некоторую нормальную обработку данных. Никаких операций пользовательского интерфейса, никаких операций. Возможно, мне следует сохранить статус обработки в состоянии, а затем отобразить их при обновлении магазина.
Но как это сделать? Поток компонентов реагирования на всю страницу? что случилось с обновлением магазина от других действий? Я имею в виду, что они больше похожи на события, чем на состояние!
Даже в худшем случае, что мне делать, если мне нужно использовать собственный диалог подтверждения или диалоговое окно с предупреждением в приложениях redux / response? Куда их ставить, действия или редукторы?
С наилучшими пожеланиями! Желаю ответить.
источник
Ответы:
Я бы так не сказал. Я думаю, что индикаторы загрузки - отличный пример пользовательского интерфейса, который легко описать как функцию состояния: в данном случае логической переменной. Хотя это правильный ответ , я хотел бы предоставить ему код.
В
async
примере в Redux репо , редуктор обновляет поле под названиемisFetching
:Компонент использует
connect()
React Redux для подписки на состояние хранилища и возвращаетсяisFetching
как частьmapStateToProps()
возвращаемого значения, поэтому оно доступно в свойствах подключенного компонента:Наконец, компонент использует
isFetching
опору вrender()
функции для отображения метки «Загрузка ...» (которая, вероятно, могла бы быть счетчиком):Любые побочные эффекты (и отображение диалогового окна, безусловно, является побочным эффектом) не относятся к редукторам. Думайте о редукторах как о пассивных «строителях государства». На самом деле они ничего не «делают».
Если вы хотите показать предупреждение, либо сделайте это из компонента перед отправкой действия, либо сделайте это из создателя действия. К моменту отправки действия уже слишком поздно выполнять побочные эффекты в ответ на него.
Для каждого правила есть исключение. Иногда логика побочных эффектов настолько сложна, что вы действительно хотите связать их либо с определенными типами действий, либо с конкретными редукторами. В этом случае обратите внимание на продвинутые проекты, такие как Redux Saga и Redux Loop . Делайте это только тогда, когда вам комфортно с ванильным Redux и у вас есть реальная проблема разрозненных побочных эффектов, которую вы хотели бы сделать более управляемой.
источник
Promise.all
в одно обещание, а затем отправить одно действие для всех выборок. Или вам нужно поддерживать несколькоisFetching
переменных в вашем состоянии.isFetching
. Он устанавливается для каждого набора извлекаемых объектов. Вы можете использовать композицию редуктора для реализации этого.RECEIVE_POSTS
никогда не запускается, знак загрузки останется на месте, если вы не создали какой-то тайм-аут для отображенияerror loading
сообщения.Отличный ответ Дан Абрамов! Просто хочу добавить, что я делал более или менее точно то же самое в одном из моих приложений (сохраняя isFetching как логическое) и в итоге мне пришлось сделать его целым числом (которое в конечном итоге считывается как количество невыполненных запросов) для поддержки нескольких одновременных Запросы.
с логическим значением:
запрос 1 запускается -> счетчик включен -> запускается запрос 2 -> заканчивается запрос 1 -> счетчик выключен -> запрос 2 завершается
с целым числом:
запрос 1 запускается -> счетчик включен -> запускается запрос 2 -> заканчивается запрос 1 -> заканчивается запрос 2 -> счетчик выключен
источник
isFetching
флагом. Если вы внимательно посмотрите на пример, который я связал, вы увидите, что существует не один объект,isFetched
а много: по одному на каждый субреддит (что и происходит в этом примере).fetchCounter
индикатор выполнения в верхней части экрана, так и несколько специальныхisFetching
флагов для списков и страниц.Хочу кое-что добавить. В реальном примере используется поле
isFetching
в магазине, чтобы представить, когда происходит выборка коллекции элементов. Любая коллекция обобщается доpagination
редуктора, который можно подключить к вашим компонентам, чтобы отслеживать состояние и показывать, загружается ли коллекция.Со мной случилось так, что я хотел получить детали для конкретной сущности, которая не вписывается в шаблон нумерации страниц. Я хотел иметь состояние, показывающее, извлекаются ли данные с сервера, но также я не хотел иметь редуктор только для этого.
Чтобы решить эту проблему, я добавил еще один универсальный редуктор под названием
fetching
. Он работает аналогично редюсеру нумерации страниц, и его задача - просто наблюдать за набором действий и генерировать новое состояние с парами[entity, isFetching]
. Это позволяетconnect
редуктору к любому компоненту и знать, получает ли приложение в настоящее время данные не только для коллекции, но и для определенной сущности.источник
Я не сталкивался с этим вопросом до сих пор, но, поскольку ответ не принят, я брошу шляпу. Я написал инструмент для этой работы: react-loader-factory . Это немного больше, чем решение Абрамова, но оно более модульное и удобное, так как мне не хотелось думать после того, как я его написал.
Есть четыре больших части:
const loaderWrapper = loaderFactory(actionsList, monitoredStates);
connect()
возвращается в Redux), так что вы можете просто прикрепить его к существующему материалу.const LoadingChild = loaderWrapper(ChildComponent);
ACTION_SUCCESS
иACTION_REQUEST
). (Вы можете отправлять действия в другое место и, конечно, просто отслеживать их из оболочки.)Сам модуль не зависит от redux-api-middleware, но я использую его именно с этим, поэтому вот пример кода из README:
Компонент с оберткой Loader:
Редуктор для мониторинга загрузчика (хотя вы можете подключить его по-другому, если хотите):
Я ожидаю, что в ближайшем будущем я добавлю в модуль такие вещи, как тайм-аут и ошибка, но шаблон не будет сильно отличаться.
Краткий ответ на ваш вопрос:
источник
Неужели я единственный, кто думает, что индикаторы загрузки не подходят Redux? Я имею в виду, я не думаю, что это часть состояния приложения как такового ...
Теперь я работаю с Angular2, и что я делаю, так это то, что у меня есть служба «Загрузка», которая предоставляет различные индикаторы загрузки через RxJS BehaviourSubjects .. Я предполагаю, что механизм такой же, я просто не храню информацию в Redux.
Пользователи LoadingService просто подписываются на те события, которые они хотят слушать.
Мои создатели действий Redux вызывают LoadingService всякий раз, когда что-то нужно изменить. Компоненты UX подписываются на открытые наблюдаемые ...
источник
Вы можете добавить слушателей изменений в свои магазины, используя либо
connect()
React Redux, либо низкоуровневыйstore.subscribe()
метод. У вас должен быть индикатор загрузки в вашем магазине, который обработчик изменений магазина может затем проверить и обновить состояние компонента. Затем компонент при необходимости отображает предварительный загрузчик в зависимости от состояния.alert
иconfirm
не должно быть проблемой. Они блокируют, и предупреждение даже не принимает никаких данных от пользователя. С помощьюconfirm
вы можете установить состояние на основе того, что пользователь щелкнул, если выбор пользователя должен повлиять на рендеринг компонента. Если нет, вы можете сохранить выбор как переменную-член компонента для дальнейшего использования.источник
addNofication(message)
. Другой случай - это предварительные загрузчики, которые также предоставляются собственным приложением хоста и запускаются его API-интерфейсом javascript. Я добавляю оболочку для этих api вcomponentDidUpdate
компонент React. Как мне спроектировать свойства или состояние этого компонента?В нашем приложении есть три типа уведомлений, все из которых разработаны как аспекты:
Все три из них находятся на верхнем уровне нашего приложения (Main) и подключены через Redux, как показано в приведенном ниже фрагменте кода. Эти свойства управляют отображением соответствующих аспектов.
Я разработал прокси, который обрабатывает все наши вызовы API, поэтому все ошибки isFetching и (api) опосредуются actionCreators, которые я импортирую в прокси. (Кроме того, я также использую webpack, чтобы создать имитацию службы поддержки для разработчиков, чтобы мы могли работать без зависимостей от сервера.)
Любое другое место в приложении, которое должно предоставить уведомление любого типа, просто импортирует соответствующее действие. Snackbar & Error имеют параметры для отображения сообщений.
) экспорт класса по умолчанию Main extends React.Component {
источник
Я сохраняю URL-адреса, такие как ::
И затем у меня есть запомненный селектор (через повторный выбор).
Чтобы сделать URL-адрес уникальным в случае POST, я передаю некоторую переменную в качестве запроса.
А там, где я хочу показать индикатор, я просто использую переменную getFetchCount
источник
Object.keys(items).filter(item => items[item] === true).length > 0 ? true : false
наObject.keys(items).every(item => items[item])
, кстати.some
вместоevery
, но да, слишком много ненужных сравнений в первом предложенном решении.Object.entries(items).some(([url, fetching]) => fetching);