#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:
Есть два способа
- используйте 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
}
- используйте завершенный обратный вызов функции (я предпочитаю это)
передайте 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 . Я попробовал оба метода, и первое решение решило проблему. Еще раз спасибо!