#redux #react-redux #redux-thunk #thunk
#сокращение #реагирование- сокращение #уменьшение количества вызовов #thunk
Вопрос:
В моем проекте React Redux я пишу thunk и хочу, чтобы он отправлялся только в том случае, если было завершено предыдущее обновление, если таковое было выполнено. Я знаю, что thunks — это методы, которые помогают нам задерживать отправку действий в редуктор, и они также могут быть асинхронными. Вот как выглядит мой thunk прямо сейчас:
myThunkMethod = () => async (dispatch, getState) =>{
dispatch(...my action...);
}
но я как могу вызвать отправку только после завершения предыдущего вызова / обновления состояния
Ответ №1:
Вот что вам нужно сделать:
const firstThunk = () => (dispatch, getState) => {
// do or dispatch something here
return Promise.resoleved("first thunk resolved");
}
const secondThunk = () => (dispatch, getState) => {
// do or dispatch something here
return Promise.resolved("second thunk resolved")
}
const thirdThunk = () => (dispatch, getState) => {
// I want to first dispatch the first thunk
dispatch(firstThunk()).then(result => {
// first thunk successfully dispatched now it's time for secondThunk
dispatch(secondThunk()).then(res => {
// here both firstThunk and secondThunk dispatched successfully
})
})
}
Комментарии:
1. спасибо за ваши усилия, но вместо thunk A, B .. и что-то конечное, я имел в виду что-то вроде: A-> A-> A-> …..-> A, где A — тот же thunk, но отправка происходит только после завершения предыдущего вызова
Ответ №2:
Вы можете комбинировать и ждать завершения выполнения, пока ваш thunk возвращает обещание : (dispatch,getState)=>Promise
.
const thunkA = (arg) => (dispatch, getState) => {
//do stuff and RETURN PROMISE
return Promise;
};
const thunkB = (arg) => (dispatch, getState) => {
//do stuff and RETURN PROMISE
return Promise;
};
//combined thunk
const combinedThunk = (arg) => (dispatch, getState) =>
tunkA(arg)(dispatch, getState).then(() =>
thunkB(arg)(dispatch, getState)
);
//from component
const Component = () => {
const dispatch = React.useDispatch();
React.useEffect(() => {
dispatch(thunkA("some arg")).then(() =>
dispatch(thunkB("someArg"))
);
}, [dispatch]);
};
Вот как вы можете выполнить рекурсивный thunk:
const recursiveThunk = (times) => (dispatch, getState) => {
if (times === 0) {
return;
}
dispatch(started());
somePromise().then(
(result) => {
dispatch(success());
return recursiveThunk(times - 1)(dispatch, getState);
},
(reject) => dispatch(failed())
);
};
Неясно, что вы хотите в своем вопросе и своем комментарии, но если вы хотите каждый раз вызывать thunkA с элементом из массива в качестве параметра, вы можете сделать это:
const combinedThunk = (args) => (dispatch, getState) => {
if (args.length === 0) {
return;
}
return tunkA(args[0])(dispatch, getState).then(
() => combinedThunk(args.slice(1))(dispatch, getState),
(reject) => dispatch(failed(reject))
);
};
//call thunkA with 1, then 2 and then 3
dispatch(combinedThunk([1, 2, 3]));
Комментарии:
1. спасибо за ваши усилия, но вместо thunk A, B .. и что-то конечное, я имел в виду что-то вроде: A-> A-> A-> …..-> A, где A — тот же thunk, но отправка происходит только после завершения предыдущего вызова
2. @DivyanshGoenka Итак, вам нужен рекурсивный thunk, я добавил его в ответ.