React js:this.state.map不是函数

时间:2018-07-15 08:02:20

标签: javascript reactjs

我尝试解决我的问题,但无法解决。 我使用Express JS创建了API,并且想显示(映射)我的状态数组。 在componentDidMount()中,我更新listOfUsers [],console.log返回正确的数据。当我想在render()中映射我的数组时,它会返回一些错误:

  

未捕获(承诺)TypeError:this.state.listOfUsers.map不是   功能

     

未捕获的TypeError:this.state.listOfUsers.map不是函数

     

警告:无法在已卸载的设备上调用setState(或forceUpdate)   零件。这是空操作,但表示您的内存泄漏   应用。要修复,请取消所有订阅和异步任务   在componentWillUnmount方法中。

enter image description here

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;

有什么建议吗?

4 个答案:

答案 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。