Search code examples
reactjsapiasynchronousreact-reduxredux-saga

How can I wait reducer update data from API on event onClick with redux and redux - Saga?


I'm struggle with the problem and I really need some help. This is my workflow: in onClick() event, I start a action to transfer a data object to reducer and to reduxSaga. When calling API is success, I use put() function in Redux Saga to update state with the response from API. Despite every operation seems to be synchronous, I get old data on the first time I click the button. Here is my code, please see and help me.

Here is my action:

export const clickToDownloadExcelFile = (data) => ({
  type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE,
  data,
});

Here is my reducer:

case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE:
      return { ...state };

    case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_SUCCESS:
      return { ...state, dataExcelFile: action.data };

    case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_FAILED:
      return { ...state };

Here is my Saga:

function* loadDataExportExcelMerchantList(actions) {
  try {
    const sendData = {
      feeCode: actions.data.feeCode,
      payChannel: actions.data.payChannel,
      typeSource: actions.data.typeSource,
      status: actions.data.status,
      merchantCode: actions.data.merchantCode,
      applyDate: actions.data.applyDate,
      expirationDate: actions.data.expirationDate,
      contract: actions.data.contract,
    };
    const data = yield call(apiFeeMerchantListExportExcel, sendData);
    yield put({
      type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_SUCCESS,
      data,
    });
  } catch (error) {
    yield put({
      type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_FAILED,
    });
  }
}

here is my onClick function:

exportFile = async () => {
    const { clickToDownloadExcelFile, dataSearch, dataExcelFile } = this.props;

    /**/ I start a action right here when I click on the button:**

    await clickToDownloadExcelFile(dataSearch);
     **// I want to get updated data from API in here. have any solution to do it?**
    console.log('dataExcelFile', dataExcelFile);

// at the first time I click on the button, dataExcelFile is null (default value). at the second click , detaExcelFile is a object which I expected it's show from the first click. };

takeLatest(constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE, loadDataExportExcelMerchantList),

I think because I call action to call Api and Update store exactly in side onClick(function), show after clickToDownLoadExcelFile run and api need some time to response, it keep doing the next code without waiting, so the result of dataExcelFile is doesn't update at the first onClick. do you have any solution for that?


Solution

  • To wait for api response, use componentDidUpdate method

    componentDidUpdate(prevProps){
      if(prevProps.dataExcelFile != this.props.dataExcelFile){
        console.log(this.props.dataExcelFile)
      }
    }