我尝试解决我的问题,但无法解决。 我使用Express JS创建了API,并且想显示(映射)我的状态数组。 在componentDidMount()中,我更新listOfUsers [],console.log返回正确的数据。当我想在render()中映射我的数组时,它会返回一些错误:
未捕获(承诺)TypeError:this.state.listOfUsers.map不是 功能
未捕获的TypeError:this.state.listOfUsers.map不是函数
警告:无法在已卸载的设备上调用setState(或forceUpdate) 零件。这是空操作,但表示您的内存泄漏 应用。要修复,请取消所有订阅和异步任务 在componentWillUnmount方法中。
import React, { Component } from 'react';
import axios from 'axios';
class MeetingItem extends Component {
state = {
meetings: [],
listOfUsers: []
}
componentDidMount() {
//get meeting info
axios.get(`http://localhost:3000/meetings/`+ this.props.match.params.id)
.then(res => {
const meetings = res.data;
this.setState({ meetings });
//console.log(res.data);
});
axios.get(`http://localhost:3000/takePart/`)
.then(res => {
for(var i = 0; i < res.data.length; i++){
//for current meeting
if(res.data[i]['meetingId'] == this.props.match.params.id){
//set listOfUsers
axios.get(`http://localhost:3000/users/`+ res.data[i]['userId'])
.then(res => {
const user = res.data;
this.setState({
listOfUsers : user
});
//in that place data is return
console.log(this.state.listOfUsers);
});
}
}
});
}
takePart = () => {
console.log("take");
const takePart = {
meetingId: this.props.match.params.id,
userId: sessionStorage.getItem('userId'),
};
//x-www-form
let formBody = [];
for (let property in takePart) {
let encodedKey = encodeURIComponent(property);
let encodedValue = encodeURIComponent(takePart[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
axios.post(`http://localhost:8000/takePart`, formBody, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
.then(res => {
console.log(res);
console.log(res.data);
//if successfully added a meeting then display alert
if(res.status == "200"){
alert("Thank you. See you later.");
}else{
alert("Sorry we can't handle that. Please repeat for a while.");
}
})
}
render() {
var users = this.state.listOfUsers.map(user => {
return (
<p>{user.firstName}</p>
)
});
return (
<div className="MeetingItem">
<h1>{/*this.props.match.params.id*/}</h1>
<p>Title: {this.state.meetings['title']}</p>
<p>Description: {this.state.meetings['description']}</p>
<p>Author: {this.state.meetings['author']}</p>
<p>lattitude: {this.state.meetings['lattitude']}</p>
<p>longitude: {this.state.meetings['longitude']}</p>
<p>date: {this.state.meetings['date']}</p>
<p>time: {this.state.meetings['time']}</p>
<p>{users}</p>
<div className="btn btn-default" onClick={this.takePart}>Take part</div>
</div>
);
}
}
export default MeetingItem;
有什么建议吗?
答案 0 :(得分:1)
API返回的用户列表应为数组。
要处理此错误,您只需在映射之前检查this.state.listOfUsers
是一个数组即可。
即
var users = Array.isArray(this.state.listOfUsers) && this.state.listOfUsers.map(user => {
return (
<p>{user.firstName}</p>
)
});
并确保返回用户列表的API axios.get('http://localhost:3000/users/'+ res.data[i]['userId'])
是预期结果的数组。
答案 1 :(得分:0)
基本上,错误表明listOfUsers不是数组(因为它没有map方法)。 看来,您的响应中有一个对象而不是数组:
axios.get(`http://localhost:3000/users/`+ res.data[i]['userId'])
.then(res => {
const user = res.data;
this.setState({
listOfUsers : user
});
答案 2 :(得分:0)
由于它不是数组,因此您可以使用如下代码:
let myState = Object.entries(this.state);
或Object.values();
这将允许您迭代其中的每一个。例如,使用Object.entries,您可以遍历每个键,值。
更多信息在这里: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
答案 3 :(得分:0)
在您的render()
函数中,更改为:
var users = this.state.listOfUsers.map(user => {
return (
<p>{user.firstName}</p>
)
});
收件人:
var users = [];
if (this.state.listOfUsers) {
user = this.state.listOfUsers.map(user => {
return (
<p>{user.firstName}</p>
)
});
}
引发异常是因为在render()
之后的钩子上首次调用componentDidMount()
时,this.state.listOfUsers
仍未定义。您需要在默认情况下将users = []
空数组设置为空,并且仅在数组变成数组时才调用map()
函数-在axios promise调用解决之后。解决axios调用后,将this.state.listOfUsers
设置为数组,然后再次调用render()
即可更新UI。