React:如何解决'Uncaught TypeError:this.state.data.map不是一个函数'

时间:2019-06-02 10:58:44

标签: javascript reactjs axios

即使我可以成功地从API将数据记录到控制台,也遇到“未捕获的TypeError:this.state.data.map不是函数”错误。 我发现了类似的问题,但是还没有找到解决此问题的好方法。

我读过here,说:“ JavaScript中的对象{}没有方法.map(),它仅适用于数组[]。” 但是,我无法弄清楚如何解决此问题,也不能遍历一个对象,也无法将数据检索到React前端。 谢谢您,任何帮助将不胜感激。

import React, { Component } from "react";
import axios from "axios";

export default class GetSubjects extends Component {
  constructor(props) {
    super(props);
    this.getsubjects = this.getsubjects.bind(this);
    this.onSearch = this.onSearch.bind(this);
    this.state = {
      keyword: "",
      data: []
    };
  }
  getsubjects(e) {
    this.setState({ keyword: e.target.value });
  }
  onSearch(e) {
    e.preventDefault();
    const searchsub = {
      keyword: this.state.keyword
    };
    axios
      .get(`http://localhost:3000/api/messages/courses/${this.state.keyword}`)
      .then(response => {
        console.log(response);
        this.setState({
          data: response.data
        });
      });
    console.log(this.state.keyword);
    console.log(this.state.data);
  }
  componentDidMount() {}

  render() {
    return (
      <div>
        <br />
        <div>
          <label>Course Name</label>{" "}
          <input
            placeholder="Enter Course Name"
            type="text"
            value={this.state.keyword}
            onChange={this.getsubjects}
            name="keyword"
            required
          />{" "}
          <button className="btn btn-primary" onClick={this.onSearch}>
            Get Subjects
          </button>
        </div>
        <br />
        <table className="table table-bordered">
          <thead>
            <tr>
              <th scope="col">Course Name</th>
              <th scope="col">Subjects</th>
            </tr>
          </thead>
          <tbody>
            {this.state.data.map(function(subject) {
              return (
                <tr>
                  {" "}
                  <td key={subject.id}>{subject.name}</td>{" "}
                  <td key={subject.id}>{subject.subjects}</td>{" "}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
}

3 个答案:

答案 0 :(得分:0)

response.dataaxios完成请求后填充的对象。 的确,您正在将data初始化为数组,但是这样做时: this.setState({ data: response.data });实际上已经将其更改为对象。

解析获得数组的对象或对返回的数据进行其他处理。

编辑:在您回复后:只需执行this.setState({data: response.data.subject});

答案 1 :(得分:0)

您说的是您收到的:

{
    "subjects": ["Computer Architecture", "Basic Networking"],
    "_id": "5cf368bfb58f8c35bc19cebc",
    "name": "Software Engineering",
    "passmark": 75,
    "lectureIncharge": "John Smith",
    "__v": 0
}

您的setState调用将data设置为该对象,该对象不是数组。

您的render代码希望它是一个数组。它尝试遍历它,并使用它来填充表中的行。但是您只会得到一条数据:一门涵盖两个主题("Software Engineering""Computer Architecture")的课程("Basic Networking")。

因此,您的render代码不应尝试将其用作数组(因此,您可能不再需要表了)。它应该直接使用data的{​​{1}}和name属性。

我现在将保留您的表标记,但是请注意,这只会产生一行(因为只有一行数据)。在subjects之前,我参加了该课程:

return

然后在其中输出表:

const course = this.state.data;

我使用了显式的<tbody> {course && course.name ? undefined : <tr> <td key={course.id}>{course.name}</td>{" "} <td key={course.id}>{course.subjects.join(", ")}</td>{" "} </tr> } </tbody> 来加入主题,而不是通过join(", ")隐式地加入主题,而在逗号后不会包含空格。

答案 2 :(得分:0)

//yo lo solucione poniendo data.data
//porque (data) solo me devolvía un objeto con varios atributos y data era uno de esos
//entonces le agregue data.data.
getCategorias(){
        axios.get("http://localhost:8000/api/categorias")
            .then(data => {   
            this.setState({
                    data: data.data
                });
            }).catch((error)=>{
                console.error(error)
            });
    }
    
    componentDidMount(){
        this.getCategorias();
        
    }