Функции обратного вызова React js

#reactjs #callback

#reactjs #обратный вызов

Вопрос:

У меня есть функция A, которая вызывается при нажатии на число. Функция A устанавливает состояние переменной и вызывает другую функцию B в качестве обратного вызова. Теперь B должен выполнить повторный вызов для получения данных из API, после чего вызывается другая функция C, которая генерирует PDF-файл с данными, полученными из API.

Проблема, с которой я сталкиваюсь, заключается в функции B, где она правильно извлекает данные из API, но я не могу передать данные следующей функции C.

Пожалуйста, помогите

     functionA = (record) =>
    {
        this.setState(
            {pdfInvoiceNum: record.no}, ()=>{
              this.functionB(record)
            });
    };

    functionB = (record) => 
    {
      this.props.getDetailForPdf(this.state.pdfInvoiceNum)  //=>This sets purchasedetail
      this.functionC(this.props.purchasedetail)           
    }

    functionC = (record) =>
    {
       console.log(record)     //Doesn't print anything when I click the first time but prints correct data when I click second time
    }


    //Click starts here
    <a onClick={()=>{this.functionA(record)}}>{text}</a>


 

Вот вызовы:

 const mapDispatchToProps = dispatch => ({
getPurchaseDetailPdf : (pdfInvoiceNum) => dispatch(fetchPurchaseDetailPdf(pdfInvoiceNum)),
});

const mapStateToProps = (state) => {
purchasedetailpdf: state.purchasesReducer.purchasedetailpdf}
};

 

purchasesAction.js

 export const fetchPurchaseDetailPdf = (number) =>  {
            console.log("PO is:"  PONumber)
                return (dispatch) => {
                    dispatch({type: FETCH_START});
                    var token = localStorage.getItem("token");
                    
                    axios.get(`${apiUrl}.../${number}`,
              ).then(({data}) => {
                          const results = data.map((row, index) => ({
                            key: index,
                            name : row.name,   
                          }))
                          dispatch({type: FETCH_SUCCESS});
                          dispatch({type: PURCHASEDETAILPDF_DATA, payload: results});
                    }).catch(function (error) {
                      dispatch({type: FETCH_ERROR, payload: error.message});
                      console.log("Error****:", error.message);
                    });
                  }
                }

 

PurchasesReducer.js

 import {FETCH_START, FETCH_SUCCESS, FETCH_ERROR, PURCHASEDETAILPDF_DATA} from '../../constants/ActionTypes';

const initialState = {
    pending: false,
    purchasedetailpdf: [],
    error: null
}

export default function purchaseReducer(state = initialState, action) {
    switch(action.type) {
        case FETCH_START: 
            return {
                ...state,
                pending: true
            }
        case FETCH_SUCCESS:
            return {
                ...state,
                pending: false,
                contracts: action.payload
            }
        case FETCH_ERROR:
            return {
                ...state,
                pending: false,
                error: action.error
            }
        case PURCHASEDETAILPDF_DATA: 
            return {
                ...state,
                purchasedetailpdf: action.payload,
            }

        default: 
            return state;
    }
}

export const getPurchaseDetailPdf = state => state.purchasedetailpdf;
export const getPurchaseDetailPdfPending = state => state.pending;
export const getPurchaseDetailPdfError = state => state.error;
 

Комментарии:

1. Является this.props.getDetailForPdf() async ли функция?

2. @ZsoltMeszaros Вот как это написано: «const mapDispatchToProps = dispatch => ({ getPurchaseDetailPdf : (pdfInvoiceNum) => dispatch(fetchPurchaseDetailPdf(pdfInvoiceNum)), }); const mapStateToProps = (состояние) => { purchasedetailpdf: состояние. purchasesReducer.purchasedetailpdf} }; « APIвызов здесь:

Ответ №1:

Есть два способа

  1. используйте async / await

сначала пусть ваше действие вернет обещание

 export const fetchPurchaseDetailPdf = (number) =>  {
  console.log("PO is:"  PONumber)
  return (dispatch) => {
    dispatch({type: FETCH_START});
    var token = localStorage.getItem("token");
                    
    return axios.get(`${apiUrl}.../${number}`)
      .then(({data}) => {
        const results = data.map((row, index) => ({
          key: index,
          name : row.name,   
        }))
        dispatch({type: FETCH_SUCCESS});
        dispatch({type: PURCHASEDETAILPDF_DATA, payload: results});

        return results;
      })
      .catch(function (error) {
        dispatch({type: FETCH_ERROR, payload: error.message});
        console.log("Error****:", error.message);
      });
  }
}
 

а затем вы можете получить результат из functionB и передать его в functionC

 functionB = async (record) => {
  const result = await this.props.getDetailForPdf(this.state.pdfInvoiceNum)  //=>This sets purchasedetail
  this.functionC(result)
}

functionC = (record) => {
   console.log(record)     //Doesn't print anything when I click the first time but prints correct data when I click second time
}
 
  1. используйте завершенный обратный вызов функции (я предпочитаю это)

передайте functionC в functionB в качестве обратного вызова, и он будет выполнен после завершения вызова api

 functionB =(record) => {
  const result = this.props.getDetailForPdf({
    number: this.state.pdfInvoiceNum,
    onCompleted: this.functionC
  })
}

functionC = (record) => {
   console.log(record)     //Doesn't print anything when I click the first time but prints correct data when I click second time
}
 

измените свое действие, чтобы принять завершенную функцию обратного вызова:

 export const fetchPurchaseDetailPdf = ({ number, onCompleted }) =>  {
  console.log("PO is:"  PONumber)
  return (dispatch) => {
    dispatch({type: FETCH_START});
    var token = localStorage.getItem("token");
                    
    axios.get(`${apiUrl}.../${number}`)
      .then(({data}) => {
        const results = data.map((row, index) => ({
          key: index,
          name : row.name,   
        }))
        dispatch({type: FETCH_SUCCESS});
        dispatch({type: PURCHASEDETAILPDF_DATA, payload: results});

        if (onCompleted) {
          onCompleted(results)
        }
      })
      .catch(function (error) {
        dispatch({type: FETCH_ERROR, payload: error.message});
        console.log("Error****:", error.message);
      });
  }
}
 

Комментарии:

1. Большое вам спасибо @chonnychu . Я попробовал оба метода, и первое решение решило проблему. Еще раз спасибо!