ReactJS:从 api 获取数据并映射数据
我正在学习 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 调用的数据,然后我返回数据。在 home 组件中,数据是使用 setState 分配的。但没有数据存储到 this.state.data 中。它始终保持未定义状态,我收到错误“TypeError:无法读取未定义的属性‘map’”。
请指导我。我应该如何打印 API 调用数据?我还想知道这个程序在进行 API 调用的性能方面是好是坏,或者还有其他更好的方法来提高性能。谢谢。
我很感激帮助。
您真的需要另一个类来获取 api 数据吗?不需要
此外,componentWillMount 方法已被弃用,因此我建议您将 axios 代码移至类中的 componentDidMount 方法。
还要用空数组而不是字符串初始化数据。并将 api 响应数据设置为状态,即数据
在渲染和显示数据时直接进行映射。
在 axios .then 和 .catch 中使用箭头函数,就像我在下面的代码中所做的那样,否则这将无法访问状态或道具。否则您需要绑定每个 .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 回答的那样,您还应该在 API 函数中
return axios....
。
编辑 2:这是更好的 API,它在错误情况下返回数据,因此您不会得到
this.state.data 不是函数
:
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.
})
}
}