React组件方法returns空数组

React component method returns empty array

对于我正在从事的项目,我编写了两个用于从 REST API 请求和解析数据的反应方法。但是,应该保存已解析数据的数组始终 returns 为空。我不确定为什么会这样。感谢任何帮助。

React 获取和解析数据的方法:

getData(){
    const { url, queries } = this.state;
    let data_arr = [];

    for (let q = 0; q < queries.length; ++q){
        let query = queries[q],
        post_query = {
            full_name: query.name,
            date_start: query.startdate,
            date_end: query.enddate
        };

        axios.post(url, post_query).then((response) => data_arr.push(response.data));
    }

    return this.setState({data: data_arr});
}
parseData(){
    const { data } = this.state;
    let dataParsed = [];

    for (let d = 0; d < data.length; ++d){
        const provider_entries = data[d];
        let provider_table = {
            name: provider_entries[0].full_name,
            size: 6,
            table: {
                rows: [],
                columns: [
                    {key: 'Date', type: 'date', filterable: true, sortable: true},
                    {key: 'Charges', type:'number', filterable:true, sortable: true},
                    {key: 'Payments', type: 'number', filterable: true, sortable: true},
                    {key: 'Appointments'}
                ]
            }
        };

        for (let p = 0; p < provider_entries.length; ++p){
            const provider_row = provider_entries[p],
            id_val = p++;
            let row = {
                id: id_val,
                Date: provider_row.date,
                Medical: provider_row.charges.medical,
                Cosmetic: provider_row.charges.cosmetic,
                Total: provider_row.charges.total,
                Payments: provider_row.payments,
                Appointments: provider_row.appointments
            };

            provider_table.table.rows.push(row);
        }

        dataParsed.push(provider_table);
    }

    return this.setState({ data_formatted: dataParsed });

}
componentDidMount(){
    this.datafetch = setInterval(() => {
        this.getData();
        this.parseData();

        const { data, data_formatted } = this.state;

        console.log(data, data_formatted);
    }, 5000);
}

来自 Rest 的数据示例 API:

[
 [
  {
   first_name: "First Name Here...", 
   last_name: "Last Name Here...",
   full_name: "Full Name Here",
   date: "2016-01-17",
   charges: {
       cosmetic: 25000.00,
       medical: 25000.00,
       total: 50000.00
   },
   payments: 75000.00,
   appointments: 99,
   pk: 5
  }, 
  {
   first_name: "First Name Here...", 
   last_name: "Last Name Here...",
   full_name: "Full Name Here",
   date: "2016-01-24",
   charges: {
       cosmetic: 25000.00,
       medical: 25000.00,
       total: 50000.00
   },
   payments: 75000.00,
   appointments: 99,
   pk: 5
  }, 
 ],
 [
  {
   first_name: "First Name Here...", 
   last_name: "Last Name Here...",
   full_name: "Full Name Here",
   date: "2016-01-17",
   charges: {
       cosmetic: 25000.00,
       medical: 25000.00,
       total: 50000.00
   },
   payments: 75000.00,
   appointments: 99,
   pk: 5
  }, 
  {
   first_name: "First Name Here...", 
   last_name: "Last Name Here...",
   full_name: "Full Name Here",
   date: "2016-01-24",
   charges: {
       cosmetic: 25000.00,
       medical: 25000.00,
       total: 50000.00
   },
   payments: 75000,
   appointments: 99,
   pk: 5
  },
 ]
];

您遇到的问题是您正在进行 ajax 异步调用并在之后立即设置状态。工作流程是:您使用 axios 进行 api 调用,将其链接到一个 .then 函数,该函数将在数据返回后执行,然后它将数据推送到您的数组中。实际的 javascript 工作流程是这样的:您进行 ajax 调用,而不是等待响应返回 javascript 继续执行并运行您的 setstate 函数。在它运行 setState 函数时,您的数据数组仍然是空的,因为没有任何响应返回。

如果是我,我会考虑使用 axios.all,它接受一组 ajax 调用,你可以将一个 .then 函数链接到它,它将是 运行 一旦完成所有 api 个调用。到那时,您可以将所有数据推送到同一个 .then 块中的数据数组和 setState 中。这将确保在数据实际返回后状态得到更新。

如果您查看这篇文章 http://codeheaven.io/how-to-use-axios-as-your-http-client/#performing-multiple-requests-simultaneously,它解释了如何一次执行多个 api 调用

像下面这样的东西应该可以工作,我没有机会测试所以我会仔细检查它但它应该做我所说的

getData(){
    const { url, queries } = this.state;
    let data_arr = [];

    // map over queries, create array of axios promises
    const axiosQueries = queries.map(function(query) {
      let post_query = {
          full_name: query.name,
          date_start: query.startdate,
          date_end: query.enddate
      };
      return axios.post(url, post_query)
    });
  // set self to be equal to react component 
  var self = this; 

  // chain all axios promises and then give the results back as an array containing each request
   axios.all(axiosQueries).then(function(results){

   // go through each result and push it into data array
     results.forEach(function(response) {
       data_arr.push(response.data)
     })

     // once all data is processed set state to data array.
     return self.setState({data: data_arr});

   })

}