Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for a redux action to finish dispatching

Tags:

reactjs

redux

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.

like image 584
Mike Rifgin Avatar asked Dec 03 '16 09:12

Mike Rifgin


People also ask

What happens when we dispatch an action in Redux?

Redux uses a "one-way data flow" app structure When something happens in the app: The UI dispatches an action. The store runs the reducers, and the state is updated based on what occurred. The store notifies the UI that the state has changed.

How do you handle async actions in Redux?

Redux Async Data Flow​ Just like with a normal action, we first need to handle a user event in the application, such as a click on a button. Then, we call dispatch() , and pass in something, whether it be a plain action object, a function, or some other value that a middleware can look for.

Is dispatch in Redux asynchronous?

Introduction. By default, Redux's actions are dispatched synchronously, which is a problem for any non-trivial app that needs to communicate with an external API or perform side effects.


1 Answers

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         )       )     })   } } 
like image 129
Alberto Centelles Avatar answered Sep 29 '22 23:09

Alberto Centelles