Попытка объединить несколько действий в моем компоненте - PullRequest
0 голосов
/ 04 сентября 2018

В моем компоненте реакции я пытаюсь связать воедино несколько действий, например:

componentDidMount() {
  dispatch(Actions.fetchUser(userId)).then(() => {
    dispatch(Actions.fetchAbc(abcId)).then(() => {
      dispatch(Actions.fetchDef(defId));
    });
  });     
}

Каждое действие следует тому же шаблону, что и fetchUser, где оно возвращает отправку:

fetchUser: (userId) => {
  return dispatch => {
    let url = "....";
    axios.get(url)
      .then(function(resp) {        
        dispatch({
          type: Constants.SomeAction,
          user: resp.data.user,
        });
      });
  };
},

В моем компоненте я вижу ошибку:

Uncaught TypeError: Невозможно прочитать свойство 'then' из неопределенного

Ошибка находится в той же строке, что и первый вызов .then (fetchUser).

Разве это не правильный способ связать воедино мои действия?

Время мудрое, я должен делать одно за другим.

1 Ответ

0 голосов
/ 04 сентября 2018

Отправка thunk возвращает возвращаемое значение функции thunk, но ваша ничего не возвращает. Попробуйте:

fetchUser: (userId) => {
  return dispatch => {
    let url = "....";
    // return the promise so you can chain on it
    return axios.get(url)
      .then(function(resp) {        
        dispatch({
          type: Constants.SomeAction,
          user: resp.data.user,
        });
      });
  };
},

Вам необходимо убедиться, что вы возвращаете обещание, возвращенное axios, поскольку это то, что вы хотите связать с последующим then.


Если посмотреть более широко на случаи, когда вы должны гарантировать, что действия отправляются в определенном порядке, то он будет немного отличаться в зависимости от того, являются ли ваши действия синхронными или асинхронными (где асинхронные действия обычно возвращают обещание).

Синхронные события просты, вы можете просто вызывать их последовательно:

dispatch(syncAction1())
dispatch(syncAction2())
dispatch(syncAction3())

Для асинхронных действий вам нужно убедиться, что каждое действие возвращает обещание, а затем объединить их в цепочку (переписав функцию componentDidMount, чтобы указать на некоторые другие проблемы):

dispatch(Actions.fetchUser(userId))
  // You need to ensure that your handler functions returns the result of the
  // next async dispatch
  .then(() => {
    return dispatch(Actions.fetchAbc(abcId))
  })
  // More simply, if you're only doing on thing then you can use the shorter
  // form of arrow function, which implicitly returns the result      
  .then(() => dispatch(Actions.fetchDef(defId))

Если у вас есть ситуации, когда вам нужна комбинация из двух, вы можете сделать это тоже:

dispatch(syncAction1())
dispatch(asyncAction2())
  .then(() => {
    dispatch(syncAction3())
    return dispatch(asyncAction4())
  })
  .then(() => dispatch(asyncAction5))

(где асинхронные действия - это групповые сообщения, которые возвращают обещание, но синхронные действия могут быть либо простыми объектами, либо синхронными групповыми операциями.)

...