组件返回TypeError:无法读取未定义的属性“ map”

时间:2019-04-29 07:36:22

标签: reactjs next.js

运行我的应用程序时,我收到以下错误消息。

TypeError: Cannot read property 'map' of undefined

我将Grid.js导入到我的Index.js文件中,如下所示。我希望Grid.js显示在Index.js页面上,但是我收到TypeError:无法读取未定义错误的属性“ map”。

Grid.js

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

class Grid extends React.Component {
  state = {
    posts: [],
    isLoading: true,
    errors: null
  };

  getPosts() {
    axios
      .get("http://localhost:1337/posts")
      .then(response => {
        this.setState({
          posts: response.data.posts,
          isLoading: false
        });
      })
      .catch(error => this.setState({ error, isLoading: false }));
  }

  componentDidMount() {
    this.getPosts();
  }
    render(){
      const { isLoading, posts } = this.state;
      return <div>
        <div className="row">

          {!isLoading ? (
            posts.map(post => {
              const { _id, title, content } = post;
              return (


    <div className="col-lg-2 col-md-3 col-sm-6 col-6" key={_id}>
        <div className="list-item slick-item r list-hover mb-3">
          <div className="media text-hover-primary">
            <span className=" media-content"><i className="fas fa-images fa-4x text-muted"></i></span> 
            <div className="media-action media-action-overlay">
              <div className="row">

                <div className="w-100 text-center mt-2 h-1x">
                Misc Meta Properties
                </div>

                <div className="w-100 text-center mt-4">
                  <a className="btn btn-sm btn-outline-light btn-rounded mx-3" href="{item.url}">View Type</a>
                </div>
              </div>
            </div>
          </div>
          <div className="list-content text-center">
            <div className="list-body">
                      <a className="list-title title" href="{item.url}">{title}</a>
                      <a className="list-subtitle d-block text-muted subtitle text-small ajax" href="{item.url}">Brand</a> 
            </div>
          </div>
        </div>
</div>  );
            })
          ) : (
            <p>

            </p>

          )}

            </div></div>

    }
  }
export default Grid; 

Index.js(Pages / index.js)

import Header from '../components/Header'
import Grid from '../components/Grid'
import Welcome from '../components/Welcome'
import Footer from '../components/Footer'
import "../style.css"

const Index = () => (
  <div>
    <body className="bg-dark">
    <Header></Header>
    <Welcome></Welcome>
    <div className="container">
        <Grid/>
        <Footer/>
    </div>
    </body>
  </div>
)

export default Index

使用NextJs的 getInitialProps 函数,我能够成功读取和显示数据。但是,我希望此API位于一个我可以调用的不错的组件文件中,而不是全部放在Index.js页面上,然后使用 this.props.title 等对其进行迭代。

有什么想法吗?

编辑:

从控制台:    [{“ id”:1,“ title”:“ test”,“ content”:“ test”,“ created_at”:1556521391304,“ updated_at”:1556521391312},{“ id”:2,“ title”:“ test “,” content“:” test“,” created_at“:1556521394698,” updated_at“:1556521394702}]

浏览至http://localhost:1337/posts/时直接从API(Strapi)获得     [{“ id”:1,“ title”:“ test”,“ content”:“ test”,“ created_at”:1556521391304,“ updated_at”:1556521391312},{“ id”:2,“ title”:“ test “,” content“:” test“,” created_at“:1556521394698,” updated_at“:1556521394702}]

5 个答案:

答案 0 :(得分:1)

您没有从服务器响应中得到posts,或者您对该响应的处理不当。

如果服务器故障时您不希望出现“错误”,则可以从{!isLoading ? (切换到{(post && post.length) ? (

答案 1 :(得分:1)

在使用地图功能之前,请确保您的数据应返回数组,并且在地图功能级别(如

)中不喊空检查
render(){
  const { isLoading, posts } = this.state;
  return <div>
    <div className="row">

      {!isLoading ? (
        posts !=null&&posts.length>0&&posts.map(post => {
          const { _id, title, content } = post;
          return (


<div className="col-lg-2 col-md-3 col-sm-6 col-6" key={_id}>
    <div className="list-item slick-item r list-hover mb-3">
      <div className="media text-hover-primary">
        <span className=" media-content"><i className="fas fa-images fa-4x text-muted"></i></span> 
        <div className="media-action media-action-overlay">
          <div className="row">

            <div className="w-100 text-center mt-2 h-1x">
            Misc Meta Properties
            </div>

            <div className="w-100 text-center mt-4">
              <a className="btn btn-sm btn-outline-light btn-rounded mx-3" href="{item.url}">View Type</a>
            </div>
          </div>
        </div>
      </div>
      <div className="list-content text-center">
        <div className="list-body">
                  <a className="list-title title" href="{item.url}">{title}</a>
                  <a className="list-subtitle d-block text-muted subtitle text-small ajax" href="{item.url}">Brand</a> 
        </div>
      </div>
    </div>

);             })           ):(             

        </p>

      )}

        </div></div>

}

答案 2 :(得分:1)

在您使用posts.map的render()方法中,第一次检查render方法时发生的反应是什么,第一次发布是一个空数组,因此在您的render方法中使用以下代码。

render(){
      var { posts } = this.state;
      var displayContent = !posts?[]:posts.map((data,index) => {
                            return {data.title}
                            })

在使用这种主要返回方法编写HTML代码之后,只需使用{displayContent}就可以了,因为它是一种简便的方法........

您指定的上述错误的发生是因为post []第一次为空。.因此,使用上面的代码就可以了...

有空时,请通过下面的链接React Life Cycle Methods。

Life Cycle Methods

答案 3 :(得分:0)

更新!isLoading吗? (posts.map(代码以及以下代码:

!isLoading && posts && Array.isArray(posts) ? posts.map(...) : ""

答案 4 :(得分:0)

我假设您正在使用nextjs。这意味着从服务器而不是客户端加载init页面。在nextjs中,有一个方法调用getinitialprops,该方法获取任何数据并创建道具。