Как отложить изменения состояния редукса, чтобы учесть побочный эффект в компоненте реакции
Извините за смутное название. Лучший способ объяснить мой вопрос может быть примером.
У меня есть элементы в избыточном списке, и этот список отображается в компоненте реакции с использованием стандартных компонентов, подключенных к реактору. Каждый отдельный элемент имеет кнопку, которая при нажатии выполняет некоторую асинхронную работу, а затем удаляет элемент из списка и помещает его в другой список, отображаемый где-то еще. Важно, чтобы логика для начала асинхронной работы была обработана в избыточности, потому что это важно для состояния моего приложения.
Эта базовая функциональность работает, но теперь я хочу добавить отзыв к кнопке, чтобы, когда побочный эффект был успешным, он менял метку на 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:
Простого стиля размонтирования, который превращает элемент в зеленый, а затем затухает, было бы достаточно для удовлетворительной обратной связи с пользователем, чтобы сказать, что все сработало.