Redux saga отправка действий изнутри карты внутри saga-action

У меня есть вызовы API следующим образом:

  1. Вызов основного api, который дает мне массив объектов.
  2. Для каждого объекта внутри массива я должен асинхронно вызывать другой API.
  3. Как только вызов вспомогательного API для объекта завершен, обновите его данные в хранилище redux, которое представляет собой массив (ofc), и покажите его.

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

Поскольку я использую redux-saga, мне нужно отправить вторую часть из redux-action. Я пробовал следующий способ:

const response = yield call(get, 'endpoint')

const configHome = response.map(function* (ele) {
    const data = yield call(get, ele.SomeURI + '?someParameter=' + ele.someObject.id)
}))

Это не работает, поскольку map ничего не знает о функциях генератора. Итак, я попробовал это:

const response = yield call(get, 'endpoint')

const configHome = yield all(response.map((ele) => {

     return call(get, paramsBuilder(undefined, ele.CategoryID))

}))

Но это заблокирует отображение доступных данных в моем пользовательском интерфейсе до тех пор, пока не будут завершены все вызовы вспомогательного API.

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

Полностью застрял на этой части. Был бы признателен за любую помощь.


person Waleed    schedule 03.06.2021    source источник


Ответы (2)


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

import { put, takeLatest, all, call } from 'redux-saga/effects';
function* _fetchNews(id) {
  const data = yield fetch(
    `https://jsonplaceholder.typicode.com/todos/${id}`
  ).then(function(response) {
    const data = response.json();
    return data;
  });
  console.log(id);
  yield put({ type: 'NEWS_RECEIVED', data });
  return data;
}

function* _getData() {
  const json = yield fetch('https://jsonplaceholder.typicode.com/todos').then(
    response => response.json()
  );
  return json;
}

function* fetchNews() {
  const json = yield _getData();
  const configHome = json.map(ele => _fetchNews(ele.id));
  for (var item of configHome) {
    yield item;
  }
}

function* actionWatcher() {
  yield takeLatest('GET_NEWS', fetchNews);
}

export default function* rootSaga() {
  yield all([actionWatcher()]);
}
person Rahul Sharma    schedule 17.06.2021
comment
Мы должны заполнить элементы на экране, как только их вызов API будет завершен. Так, например, если есть 10 вызовов API, которые когда-либо разрешаются первыми, мы их отобразим. - person Waleed; 17.06.2021
comment
@Waleed Проверьте сейчас, я обновил образец. - person Rahul Sharma; 17.06.2021

yield all - генератор заблокирован до разрешения всех эффектов или как только один будет отклонен

Таким образом, вам нужно будет отправлять события отдельно для каждого подчиненного API.

Предположим, у вас есть 2 действия:

export const getMainApi =() => ({
  type: types.GET_MAIN_API,
});

export const getSubApi = endpoint => ({
  type: types.GET_SUB_API,
  endpoint,
});

Тогда ваши операции будут:

const get = endpoint => fetch(endpoint).then(response => response);

function* fetchMainApi(action) {
  try {
    const response = yield call(get, 'endpoint');
    for (let i = 0; i < response.length; i += 1) {
      // dispatch here all sub APIs
      yield put(
        getSubApi(
          response[i].SomeURI + '?someParameter=' + response[i].someObject.id,
        ),
      );
    }
  } catch (e) {
    console.log(e);
  }
}

function* fetchSubApi(action) {
  try {
    const response = yield call(get, action.endpoint);
    yield put({
      type: types.RECEIVE_SUB_API,
      response
    });
  } catch (e) {
    console.log(e);
  }
}

takeLatest(type.GET_MAIN_API, fetchMainApi)
takeEvery(types.GET_SUB_API, fetchSubApi)

Итак, при успешном получении суб-API вам необходимо вставить данные в ваше состояние внутри редукторов.

Это просто псевдокод.

person Observer    schedule 22.06.2021