Search code examples
reactjsredux

Wait for a redux action to finish dispatching


I have the following action creator:

export function scrolltoNextItem(item) {
  return (dispatch, getState) => {
    dispatch(appendItem(Item));
    dispatch(
      scrollToNextIndex(
        getState().items.length - 1
      )
    )
  }
}

Problem is that scrollToNextItem runs before appendItem has finished and the scroll position ends up being incorrect. I can prove this is the case by adding a setTimeout to make the execution of the script wait for the next tick before running scrollToNextItem:

export function scrolltoNextItem(item) {
  return (dispatch, getState) => {
    dispatch(appendItem(Item));
    setTimeout(() => {
      dispatch(
        scrollToNextIndex(
          getState().items.length - 1
        )
      )
    }, 0);
  }
}

How can I wait for the appendItem action to finish? In standard react land I would just use the setState callback:

this.setState({something: 'some thing'}, () => {
  console.log('something is set');
});

But dispatch doesn't provide any callback functionality.


Solution

  • You can always wrap appendItem into a promise and pass dispatch as an argument to it

    const appendItem = (item, dispatch) => new Promise((resolve, reject) => {
      // do anything here
      dispatch(<your-action>);
      resolve();
    }
    

    Then you can call it like this from scrolltoNextItem

    export function scrolltoNextItem(item) {
      return (dispatch, getState) => {
        appendItem(Item, dispatch).then(() => {
          dispatch(
            scrollToNextIndex(
              getState().items.length - 1
            )
          )
        })
      }
    }