简体   繁体   中英

How can I make a function Async in reactjs which calls another two functions from redux actions

I am using react, with redux for state management. In my UI I have a button which when clicked it calls a function and that function internally calls 2 redux actions that perform the specific task. The problem is my function when I make a call after a click of the button it immediately calls both the functions.

This is my on button click function

const handleDecrement = (productId) => {
    props.minusQuantity(productId, props.guestIdData); // call make to redux action to perform API action

    props.quantityData.forEach((item) => {
        if (item.productQuantity < 1) {  // value of state. Which is instantly changed
            props.removeWholeItem(productId); // Another API call to redux action 
        }
    });
};

I want to call this function first

props.minusQuantity(productId, props.guestIdData); 

and thnen later the following code

props.quantityData.forEach((item) => {
        if (item.productQuantity < 1) {  // value of state. Which is instantly changed
            props.removeWholeItem(productId); // Another API call to redux action 
        }
    });

Use redux-thunk and bind your button onClick function as async.

handleClick = async () => {
  await props.actions.someReduxThunkFn();
  await props.actions.otherReduxThunkFn();
}

You can use.then and.catch and makes function calls one after another.

props.minusQuantity(productId, props.guestIdData).then(response=>{ props.removeWholeItem(productId) })

Assuming that minusQuantity is a thunk action that returns a promise you can await it:

const minusQuantity = (productId, guestIdData) => (
  dispatch,
  getState
) => {
  return Promise.resolve('async value');
};

Now both of the other answers would work:

const handleDecrement = async (productId) => {
  await props.minusQuantity(productId, props.guestIdData); 

or

const handleDecrement = (productId) => {
  props.minusQuantity(productId, props.guestIdData).then(
    ()=>{
      //do other stuff here
    }
  )

Working example:

 const { Provider, connect } = ReactRedux; const { createStore, applyMiddleware, compose } = Redux; const initialState = {}; //action types const BEFORE_ASYNC = 'BEFORE_ASYNC'; const AFTER_ASYNC = 'AFTER_ASYNC'; //action creators const minusQuantity = () => (dispatch) => { dispatch({ type: BEFORE_ASYNC }); //note it is returning a promise return new Promise((resolve) => setTimeout( () => resolve(dispatch({ type: AFTER_ASYNC })), 2000 ) ); }; const reducer = (state, { type }) => { console.log('reducer called with action:', type); return state; }; //creating store with redux dev tools const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( reducer, initialState, composeEnhancers( applyMiddleware((store) => (next) => (action) => typeof action === 'function' //DIY thunk middleware? action(store.dispatch): next(action) ) ) ); const App = (props) => { const handleDecrement = (productId) => { console.log('in handeDecrement starting async action'); props.minusQuantity(productId).then(() => console.log('in handleDecrement after async action') ); }; return ( <button onClick={handleDecrement}> start async action </button> ); }; const AppContainer = connect(undefined, { minusQuantity, })(App); ReactDOM.render( <Provider store={store}> <AppContainer /> </Provider>, document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM