ReactJS:从 api 获取数据并映射数据

IT技术 reactjs
2021-05-18 09:06:45

我正在学习 ReactJS。在我的程序中,我进行了 API 调用,然后进行了映射。API调用获取的数据是这样的, data = [{"uid":"1", "title":"hello"},{"uid":"2", "title":"World"}]

import ImporterAPI from '../api';
const API = new ImporterAPI();

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: ''
  }}

  componentWillMount() {
    this.setState({ data: API.getData()}, () => {
      console.log("data fetched");
      var mapData = []
      this.state.data.map( (object, i) => {
        mapData.push(<p key={i}>{object}</p>)
      })
  }) 
  }

  render() {
    return (
      <div className="home">
        {this.mapData}
      </div>
    )
  }
}

还有我的 API 文件,

import axios from 'axios';
class API {
  getData = () => {
    axios.get('http://localhost:8005/data')
    .then(function (response) {
      if (response.status === 200 && response != null) {
        var data = response.data;
        console.log(data)
        return data
      } else {
        console.log('problem');
      }
    })
    .catch(function (error) {
      console.log(error);
    });
  }
}

我的 console.log 正在打印来自 API 调用的数据,然后我正在返回数据。使用 setState 分配家庭组件数据的位置。但是没有数据存储到 this.state.data 中。它始终保持未定义状态,并且出现错误“TypeError:无法读取未定义的属性‘地图’”。

请指导我。我应该如何打印 API 调用数据 & 我还想知道这个程序在进行 API 调用的性能方面是好是坏,或者是任何其他更好的提高性能的方法。谢谢。

我将不胜感激。

2个回答

你真的需要另一个类来获取 api 数据吗?不需要

此外,不推荐使用 componentWillMount 方法,因此我建议您将 axios 代码移动到类中的 componentDidMount 方法。

还用空数组而不是字符串初始化数据。并将api响应数据设置为state即data

直接在渲染和显示数据中进行映射。

在 axios .then 和 .catch 中使用箭头函数,就像我在下面的代码中所做的那样,否则将无法访问状态或props。你需要绑定每个 .then 和 .catch 否则

您的代码可以简化如下

     class Home extends Component {
         constructor(props) {
            super(props);
            this.state = {
               data: []
            }
         }

      componentDidMount() {
          axios.get('http://localhost:8005/data')
            .then(response => {
                if (response.status === 200 && response != null) {
                  this.setState({
                       data: response.data
                  });
           } else {
             console.log('problem');
           }
      })
      .catch(error => {
          console.log(error);
      });
    }

    render() {
       const { data } = this.state;
       return (
          <div className="home">
            {Array.isArray(data) && data.map(object => (
                 <p key={object.uid}>{object.title}</p>
             ))}
          </div>
        )
    }
  }

您的代码中有两个问题。

首先,API.getData()是一个异步函数。这意味着当您调用 时API.getData(),数据不会中间返回(认为获取数据需要几毫秒)。你应该setState在获取数据后。

其次,您应该在render函数中发送渲染逻辑

它应该是这样的:

import React, { Component } from 'react'
import ImporterAPI from '../api'
const API = new ImporterAPI()

class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: []
    }
  }

  componentWillMount() {
    API.getData().then(response => {
      console.log('Data fetched', response)
      this.setState({
        data: response
      })
    })
  }

  render() {
    return (
      <div className="home">
        {this.state.data.map((object, index) => (
          <p key={index}>{object}</p>
        ))}
      </div>
    )
  }
}

作为@Askiron 的回答,您还应该return axios....在 API 函数中。

编辑 2:这是更好的 API,它在错误情况下返回数据,因此您不会得到this.state.data is not a function

import axios from 'axios'

class API {
  getData = () => {
    return axios
      .get('http://localhost:8005/data')
      .then(function(response) {
        if (response.status === 200 && response != null) {
          var data = response.data
          return data
        } else {
          throw new Error('Empty data')
        }
      })
      .catch(function(error) {
        console.log(error)
        return [] // Return empty array in case error response.
      })
  }
}