React Redux - дождаться загрузки данных - PullRequest
3 голосов
/ 06 ноября 2019

Я использую Redux (+ thunk) для получения данных из моего API. Я реализовал компонент Data Fetcher, который вызывает все действия и после выполнения отправляет LOADED. В моем фактическом основном компоненте, где я рендерим контент, я жду, пока флаг isLoaded в реквизитах не будет установлен в true.

Вот метод в сборщике данных:

const fetchData = () => {
    if (isAuthenticated) {
        const p = [];
        p.push(fetchDataSetOne());
        p.push(fetchDataSetTwo());
        Promise.all(p).then( () => setHasLoaded() );
    }
}

Каждый изэти методы извлечения возвращают обещание axios, в котором я отправляю один раз извлеченные данные следующим образом:

export const fetchDataSetOne = () => dispatch => {
  return axios.get(`${API_URL}/dataSetOne`)
    .then(res => {
        dispatch({
            type: FETCH_ALL_DATA_SET_ONE,
            payload: res.data.docs
        });
    });
};

В функции рендеринга моего компонента я рендерирую содержимое только при загрузке (которая устанавливается диспетчером LOADED из setHasLoaded action) примерно так:

{ hasLoaded && <MyContent> }

Несмотря на то, что я «жду» завершения действий (= Promise.all), моя переменная hasLoaded имеет значение true, прежде чем будут установлены выбранные данные. Кто-нибудь может помочь?

1 Ответ

1 голос
/ 06 ноября 2019

Проблема в том, что вы возвращаете функцию, а не обещание.
Это разрешается немедленно.

См. Рабочий пример кода

export const fetchData2 = dispatch => () => {
  dispatch({type: 'START_FETCH'})
  const p = [
    fetchDataSetOne(dispatch),
    fetchDataSetTwo(dispatch)
  ];
  Promise.all(p).then((res) => setHasLoaded(res));
};

// this returns a promise AFTER it calls an action
const fetchDataSetOne = dispatch => {
  return axois.get(`${API_URL}/dataSetOne`).then(res => {
    dispatch({
      type: "FETCH_ALL_DATA_SET_ONE",
      payload: res.data.docs
    });
  });
};

Это разрешается после разрешения обоих обещаний, но состояние обновляется после разрешения каждого обещания. Чтобы обновить состояние после разрешения всех обещаний, попробуйте следующее:

export const fetchData3 = dispatch => () => {
  dispatch({ type: "START_FETCH" });
  const p = [
    axois.get(`${API_URL}/dataSetOne`),
    axois.get(`${API_URL}/dataSetTwo`)
  ];
  Promise.all(p).then(callActions(dispatch));
};

const callActions = dispatch => res => {
  dispatch({
    type: "FETCH_ALL_DATA_SET_ONE",
    payload: res[0].data.docs
  });
  dispatch({
    type: "FETCH_ALL_DATA_SET_TWO",
    payload: res[1].data.docs
  });
  setHasLoaded(res);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...