Answer the question
In order to leave comments, you need to log in
How to wait for all data given React Redux Async Recursion construct?
There is a file actions
in which there are asynchronous requests, but one request needs to be made recursive so as not to send a huge request, but to take it in small pieces. Everything seems to be nothing, but only the drawing comes faster than the last piece is saved in the Redux
State
Example:
myRecursion = (cb) => { // Рекурсивная функция, которую будем вызывать дальше при выполнении реквеста
return new Promise(() => {
Api
.getSomeData(request)
.then(response => {
dispatch(actionHandler(response.item)) // Диспатчим новые айтемы
if(response.items.length){
myRecursion(); // Если есть еще данные, вызываемся снова
return false;
}
return true;
})
.then(() => cb()) // Вызываем колбек, который является resolve, чтоб зарезолвить промис.
})
}
// Ниже главные функционал реквестов
const promise = new Promise(resolve => {
const requests = someData.reduce() // тут собирается пачка реквестов
Promise
.all(requests) // резолвим все реквесты
.then(response => {
response.forEach((item, i) => {
dispatch(actionHandler(item)); // Диспатчим, всё ок
if(item.type определенного типа мы его загоняем в рекурсию){ // необходимое условие для определенного реквеста
myRecursion(resolve) // Та самая рекурсия. Я решил запихнуть туда resolve, чтоб его вызвать колбеком по завершению всех следующих реквестов
}
})
});
});
promise.then(() => {
// По идее все реквесты закончились, но последний резвест не успевает сохраниться в Redux State, и отрисовка некоторых данных получается некорректная, все предыдущие запросы рисуются отлично
})
Answer the question
In order to leave comments, you need to log in
Why do you need recursion? Looks like a set of crutches. Try to solve the problem in a different way. For example, pick up data in one request, or implement an infinite scroll with data loading on demand.
The redraw happens when you update the store . Nothing surprising.
If so you want to leave and use your approach. You have two ways:
1. Add the isAllDataLoaded key to the store and update it in the reducer when the last piece of data arrives.
2. Add redux-thunk to the project to the project . Rewrite your function in async action :
const fetchData = () => async dispatch => {
const data = [];
try {
while(true) {
const response = await Api.getSomeData({ from: data.length });
data.push(response.item); // если item это массив, то data.push(...response.item);
if(!response.items.length) {
break;
}
}
dispatch(fetchDataSuccess(data));
return data;
} catch (e) {
dispatch(fetchDataFail(e));
}
};
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question