Axios返回空数组,然后返回数据

时间:2019-08-09 01:13:10

标签: javascript reactjs rest api axios

我有一个简单的react应用程序,该应用程序从API提取数据并将其打印到控制台。 我正在使用Axios从API获取值。 这是API:https://mobile-tha-server-8ba57.firebaseapp.com/walmartproducts/1/20

import React, { Component } from 'react';
import axios from 'axios';

class Products extends Component {
    state = {
        MetaProducts: []
    }
    async componentDidMount(){
        const res = await axios.get('https://mobile-tha-server-8ba57.firebaseapp.com/walmartproducts/1/20')
        this.setState({ MetaProducts: res.data.products});
    }

    render() {
        console.log(this.state.MetaProducts);
        return(
            <div>
                Products
            </div>

        )
    }
}


export default Products;

但是Axios首先返回一个空数组,然后返回包含数据的数组。

控制台:
Products.js:14 []
Products.js:14(20)[{…},{…},{…},{…},{…},{…},{…},{…},{…},{…},{ …},{…},{…},{…},{…},{…},{…},{…},{…},{…}]

3 个答案:

答案 0 :(得分:3)

这是因为在React中,componentDidMount在render方法之后被调用。

https://reactjs.org/docs/react-component.html#mounting处检查React生命周期方法。

它将首先记录空数组,这是默认状态,然后记录axios api调用返回的内容。

答案 1 :(得分:1)

您是指控制台上的空数组吗?当然。它将打印空数组。您必须看一下反应生命周期。 Render将首先运行,然后下一个是componentDidMount。因为您将MetaProducts初始化为一个空的错误,这就是为什么它将首先打印并清空数组的原因。

答案 2 :(得分:1)

这是由于反应生命周期的异步行为。在您的axios请求完成之前调用了渲染,并且this.state.Metaproducts从未在render内部更新,因为它已经在您的请求之前渲染了。 您可以等待来自axios的回调,然后再更新状态,并确保在ajax完成后呈现产品。

我又添加了一个状态变量init,并在从服务器获得响应后将其设置为true。默认情况下,init为假,然后您可以显示“正在加载消息”。

希望对您有帮助

import React, { Component } from 'react';
import axios from 'axios';

class Products extends Component {
  state = {
    MetaProducts: [],
    init:0,
  }

  async componentDidMount() {
   await axios.get('https://mobile-tha-server-8ba57.firebaseapp.com/walmartproducts/1/20').then(res => {
      this.setState({ MetaProducts: res.data.products, init:1 });
    });
  }

  renderProduct() {
    return <ul>
    {this.state.MetaProducts.map(p =>
      <li>
        {p.productName}
      </li>
    )};
    </ul>;
  }

  render() {
    return this.state.init ? <div>{this.renderProduct()}</div> : <div>loading...</div>;
   }
}



export default Products;