Как я могу сделать функцию Asyn c в reactjs, которая вызывает еще две функции из действий redux - PullRequest
1 голос
/ 07 августа 2020

Я использую реакцию с редукцией для управления состоянием. В моем пользовательском интерфейсе есть кнопка, которая при нажатии вызывает функцию, и эта функция внутренне вызывает 2 действия redux, которые выполняют определенную задачу c. Проблема в моей функции, когда я звоню после нажатия кнопки, она сразу вызывает обе функции.

Это моя функция нажатия кнопки

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 
        }
    });
};

Я хочу вызвать это сначала функция

props.minusQuantity(productId, props.guestIdData); 

, а затем следующий код

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

Ответы [ 3 ]

1 голос
/ 07 августа 2020

Вы можете использовать .then и .catch и выполнять вызовы функций один за другим.

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

1 голос
/ 07 августа 2020

Предполагая, что minusQuantity - это действие преобразователя, которое возвращает обещание, которое вы можете дождаться:

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

Теперь оба других ответа будут работать:

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

или

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

Рабочий пример:

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>
1 голос
/ 07 августа 2020

Используйте redux-thunk и привяжите свою кнопку к функции onClick как asyn c.

handleClick = async () => {
  await props.actions.someReduxThunkFn();
  await props.actions.otherReduxThunkFn();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...