Как вызвать последовательное действие одно за другим - и убедиться, что оба они визуализируются (реагировать на избыточность)?

Я хочу добавить элемент, используя POST запрос, затем закройте всплывающее окно и обновите список элементов с помощью GET запрос. С помощью redux-thunkЯ мог бы назвать 2 последних действия после получения результата от POST,

Теперь я хочу вызвать действие loadAll, чтобы заполнить обновленный список элементов и завершить изменение состояния / рендеринг перед вызовом toggleAddItem, который фактически закрывает всплывающее окно.

export const loadAllItems = items => ({
    type: LOAD_ALL_ITEMS,
    payload: items
});

export const toggleAddItem = status => ({
    type: TOGGLE_ADD_ITEM,
    payload: status
})

export const loadAll = () => (dispatch => {
    axios.get('/getAllItems').then(res => {
        dispatch(loadAllItems(res.data))
    })
    .catch(err => {
        console.log(err);
    })
});

export const addItemAndRefresh = input => ((dispatch, getState) => {
axios.post('/addItem', input)
  .then(() => {
      axios.get('/getAllItems')
      .then(res => {
          dispatch(loadAll(res.data))
      })
      .then(() => {
          dispatch(toggleAddItem(false));
      })
  })
  .catch(err => {
      console.log(err);
  })
});

С помощью приведенного выше кода мне удается вызвать loadAll перед toggleAddItem. Однако с журналом componentDidUpdate я понимаю, что toggleAddItem фактически срабатывает, когда loadAll все еще обновляет состояние / рендеринг и даже завершает работу перед предыдущим действием.

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

Какова будет лучшая реализация для отправки последовательных действий и обеспечения того, что оба будут выполнены?

1 ответ

Вам нужно позвонить then по обещанию, возвращенному из loadAll действие.

Сначала верните это обещание, изменив loadAll чтобы:

export const loadAll = () => dispatch => {
    return axios.get('/getAllItems')
      .then(res => {
          dispatch(loadAllItems(res.data))
      })
      .catch(err => {
          console.log(err);
      })
};

Тогда в вашем mapDispatchToProps вызов then а затем передать функцию, которая будет вызываться, когда loadAll решает.

const mapDispatchToProps = dispatch => ({
  addItemAndRefresh: dispatch(loadAll())
                      .then(() => dispatch(toggleAddItem(false)))
});
Другие вопросы по тегам