【问题标题】:React js: this.state.map is not a functionReact js:this.state.map 不是函数
【发布时间】:2018-12-23 02:17:31
【问题描述】:

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

Uncaught (in promise) TypeError: this.state.listOfUsers.map is not a 功能

未捕获的类型错误: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;

有什么建议吗?

【问题讨论】:

  • 检查res.data。我确信它不是一个数组。 map是Array的方法之一,所以会报错。

标签: javascript reactjs


【解决方案1】:

API 返回的用户列表应该是一个数组。

要处理此错误,您可以在 map 之前检查 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']) 返回的用户列表是预期结果的数组。

【讨论】:

    【解决方案2】:

    因为它不是一个数组,你可以使用这样的东西:

    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】:

      基本上,错误说 listOfUsers 不是数组(因为它没有 map 方法)。 看来,您的响应中有一个对象而不是数组:

      axios.get(`http://localhost:3000/users/`+ res.data[i]['userId'])
                .then(res => {
                  const user = res.data;
                  this.setState({ 
                    listOfUsers : user
                  });
      

      【讨论】:

        【解决方案4】:

        在您的 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>
               )
            });
        }
        

        原因

        抛出异常是因为当componentDidMount()之后的钩子第一次调用render()时,this.state.listOfUsers仍然未定义。您需要默认设置users = [] 空数组,并且只有在数组变成数组时才在数组上调用map() 函数 - 在 axios 承诺调用解决后。解决 axios 调用后,它会将 this.state.listOfUsers 设置为数组,并再次调用 render() 以更新 UI。

        【讨论】:

          猜你喜欢
          • 2016-09-02
          • 2023-03-27
          • 2020-09-11
          • 2021-07-20
          • 2016-11-21
          • 2020-12-04
          • 2021-07-11
          • 2015-09-01
          • 2015-08-22
          相关资源
          最近更新 更多