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

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

switch (action.type) {

case RELEASE_PAYMENT:

(new PaypalContract())
            .releasePayment(action.id)
            .then(() => (new PaypalContract()).getState(action.id))
            .then(function(e) {
                console.log("status in orderReducer:",status[e])
                return{
                  ...state,
                  orderStatus: status[e]
                }
            })
return state

person Chan Austin    schedule 17.10.2020    source источник
comment
Для взаимодействия с асинхронной функцией, такой как выборка данных или базовый смарт-контракт, я думаю, что было бы неплохо поместить функции либо в редуктор, либо в действие, а не в компонент реакции. Так как успешная асинхронная функция сначала обратится к «ожидающему», а затем после получения требуемых данных вернет «выполнено». Так что в этой ситуации мне действительно может понадобиться «redux-prom-middleware». Мне нужно что-то изменить в действии и редукторе, чтобы он работал: github.com/pburtchaell/redux-promise-middleware/blob/main/docs/   -  person Chan Austin    schedule 18.10.2020


Ответы (2)


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

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

Функции редуктора являются синхронными, они принимают действие и на основе действия возвращают обновленное состояние. Все это происходит синхронно.

То, что вы делаете в своей функции редуктора, не будет работать так, как вы ожидаете, и оператор return в вашей функции редуктора всегда будет выполняться до завершения асинхронного кода. Это означает, что ваша функция reducer всегда возвращает одно и то же состояние, что означает, что ваше хранилище redux никогда не обновляется.

Решение

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

Ниже приведены несколько вариантов, которые позволят вам это сделать:

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

Вот несколько ресурсов, которые помогут вам начать работу с каждым из упомянутых выше вариантов:

person Yousaf    schedule 17.10.2020
comment
Похоже, что redux thunk и redux saga используются для реагирования компонентов на асинхронную выборку. Для того, чтобы react / redux взаимодействовал со смарт-контрактом в блокчейне, я думаю, было бы лучше поместить это взаимодействие либо в действие, либо в редуктор, а не в компоненты пользовательского интерфейса. Редуктор синхронизируется, поэтому, возможно, было бы лучше иметь модуль действий для отправки большего количества сообщений редуктору, таких как «ожидает», «выполнено», я поискал в сети, а затем обнаружил, что промежуточное ПО redux-обещание может быть тем, что мне нужно. Спасибо за совет. - person Chan Austin; 18.10.2020
comment
redux-promise-middleware также будет работать, но redux-thunk и redux-saga тоже будут делать то, что вы хотите. Компонент React просто отправляет действие для запуска процесса выборки данных, а фактическая выборка данных происходит вне компонента. Вы можете использовать любой из них для достижения желаемого результата. - person Yousaf; 18.10.2020

Вам необходимо передать данные редуктору после получения ответа от API. Управлять потоком данных будет проще. Вы можете использовать async/await в этом.

async function_name() {
   const res = await API_CALL_HERE
   res.then( data => INVOKE_YOUR_DISPATCH_HERE(data))
      .catch(err => console.log('error'));
}

В редукторе

 case RELEASE_PAYMENT:
  return {...state, orderStauts:data[e]
person Sathishkumar Rakkiasamy    schedule 17.10.2020