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

Извините за смутное название. Лучший способ объяснить мой вопрос может быть примером.

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

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

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

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

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

Кто-нибудь имел дело с такой проблемой раньше?

Спасибо

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

2 ответа

Решение

Вы упомянули, что вы используете redux-loop чтобы обрабатывать ваши асинхронные вещи. Я более знаком с redux-thunkтак что если с тобой все в порядке, я дам тебе ответ, который использует thunk.

Вы можете оставить свой код СУХИМ, если вы установите тайм-аут в создателе действия, а затем вызовете этого создателя действия с помощью нескольких кнопок:

// actionCreators.js

const fetchTheThings = (url, successAction, failureAction, followUpAction) => (dispatch) => {

  //if you put the app in an intermediate state
  //while you wait for async, then do that here
  dispatch({ type: 'GETTING_THINGS' });

  //go do the async thing
  fetch(url)
    .then(res => {
      if (res.status === 200) return res.json();
      return Promise.reject(res);
    })
    .then(data => {
      //on success, dispatch an action, the type of which
      //you passed in as an argument:
      dispatch({ type: successAction, data });

      //then set your timeout and dispatch your follow-up action 1s later
      setTimeout(() => {
        dispatch({ type: followUpAction });
      }, 1000);
    })
    .catch(err => {
      //...and handle error cases
      dispatch({ type: failureAction, data: err });
    });
};

//then you can have exported action creators that your various buttons call
//which specify the action types that get passed into fetchTheThings()

export const actionFiredWhenButtonOneIsPressed = () => {
  return fetchTheThings('<some url>', '<success action>', '<failure action>', '<follow-up action>');
};

export const actionFiredWhenButtonTwoIsPressed = () => {
  return fetchTheThings('<other url>', '<other success action>', '<other failure action>', '<other follow-up action>');
};

Надеюсь, что по крайней мере, дает вам некоторые идеи. Удачи!

Решение Яна должно быть достаточно хорошо обобщаемо, но, может быть, если вы можете жить с подтверждением успеха, которое не требует активности DOM:

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

Другие вопросы по тегам