【问题标题】:React: "TypeError: props.category is undefined" when accessing key of categoryReact:访问类别键时出现“TypeError:props.category is undefined”
【发布时间】:2020-10-31 21:18:55
【问题描述】:

我从后端接收 JSON 对象,其中包含名称 category,其值为对象。此对象包含名称 _idname。但是当我使用props.category._id 访问_id 时,它给了我这个错误:

TypeError: props.category is undefined

其实JSON对象就是MongoDB的文档,category是包含对另一个文档的引用的字段。

后端是用 Node.js 编写的,我使用的是 Mongoose。

我可以共享所需部分的后端和前端代码。

App.js

<Route path="/blog/:id" exact><SinglePost /></Route>

singlepost.js:页面的反应组件(SinglePost)

import React, { Component } from 'react';
import { withRouter } from 'react-router';
import axios from 'axios';
import Comments from '../parts/comments';
import RelatedPosts from '../parts/relatedpost';
import BlogContent from '../parts/blogcontent';

class SinglePost extends Component 
{
  constructor(props)
  {
    super(props);
    this.state = {
      blog: [],
      commentCount: []
    };
  }

  componentDidMount()
  {
    axios.get('http://localhost:5000/blogs/get/' + this.props.match.params.id)
    .then(res => {
      this.setState({
        blog: res.data
      });
    })
    .catch(err => console.log(err));

    axios.get('http://localhost:5000/comments/count/' + this.props.match.params.id)
    .then(res => {
      this.setState({
        commentCount: res.data
      });
    })
    .catch(err => console.log(err));
  }

  render()
  {
    return (
      <div>


      <section className="blog-section">
        <div className="container">
          <div className="single-post no-sidebar">
            <div className="title-single-post">
              <a className="text-link" href="#"></a>
              <h1>{this.state.blog.title}</h1>
              <ul className="post-tags">
                <li>{new Date(this.state.blog.createdAt).toDateString()}</li>
                <li><a href="#">{this.state.commentCount.count} comments</a></li>
              </ul>
            </div>
            <div className="single-post-content">
              <img src={"../../" + this.state.blog.imageUrl} alt="" />
              <div className="post-content">
                <div className="post-social">
                  <span>Share</span>
                  <ul className="share-post">
                    <li><a href="#" className="facebook"><i className="fa fa-facebook"></i></a></li>
                    <li><a href="#" className="twitter"><i className="fa fa-twitter"></i></a></li>
                    <li><a href="#" className="pinterest"><i className="fa fa-pinterest"></i></a></li>
                  </ul>
                </div>
                <BlogContent blog = {this.state.blog} />
              </div>
              <RelatedPosts category = {this.state.blog.category} />
              
            </div>

            <Comments />

          </div>
            </div>
        </section>

    </div>
    );
  }
}

export default withRouter(SinglePost);

relatedposts.js : 相关帖子的 React 组件(RelatedPosts)

import React from 'react';
import axios from 'axios';

let RelatedPost = props => (
    <div className="col-lg-4 col-md-4">
        <div className="news-post standard-post text-left">
            <div className="image-holder">
                <a href="single-post.html"><img src={"../../" + props.currentPost.imageUrl}  alt="" /></a>
            </div>
            <a className="text-link" href="#">{props.currentPost.category.name}</a>
            <h2><a href="single-post.html">{props.currentPost.title}</a></h2>
            <ul className="post-tags">
                <li>{new Date(this.state.blog.createdAt).toDateString()}</li>
            </ul>
        </div>
    </div>
);

const RelatedPosts = (props) => {
    var relatedPosts = [];
    axios.get('http://localhost:5000/get/related-posts/' + props.category._id)
    .then(res => {
        relatedPosts = res.data;
    })
    .catch(err => console.log(err));

    return (
        <div className="related-box">
            <h2>Related Posts</h2>
            <div className="row">
                {relatedPosts.map((currentPost, index) => {
                    return <RelatedPost currentPost = {currentPost} key = {index} />
                })}
            </div>
        </div>
    );
}

export default RelatedPosts;

来自后端的 JSON

{"featured":false,"likes":5,"_id":"5f084b96acb1d60bcee3f0fa","title":"Lorem Ipsum","description":"Lorem Ipsum Blog","imageUrl":"upload/blog/f1.jpg","category":{"_id":"5f05ae4b27ef066f94673265","name":"Technology"},"createdAt":"2020-07-10T11:05:58.044Z","updatedAt":"2020-07-10T11:05:58.044Z","__v":0}

【问题讨论】:

  • 你能发布你的反应代码
  • 我将代码添加到我的问题中。你可以检查一下。

标签: javascript node.js reactjs mongodb mongoose


【解决方案1】:

像这样更改SinglePost 组件,您将在其中检查数据是否已到达并设置在您的状态。 您可以按照以下方式进行操作

SinglePost.js

import React, { Component } from 'react';
import { withRouter } from 'react-router';
import axios from 'axios';
import Comments from '../parts/comments';
import RelatedPosts from '../parts/relatedpost';
import BlogContent from '../parts/blogcontent';

class SinglePost extends Component {
  constructor(props)
  {
    super(props);
    this.state = {
      blog: [],
      commentCount: []
    };
  }

  componentDidMount()
  {
    axios.get('http://localhost:5000/blogs/get/' + this.props.match.params.id)
    .then(res => {
      this.setState({
        blog: res.data
      });
    })
    .catch(err => console.log(err));

    axios.get('http://localhost:5000/comments/count/' + this.props.match.params.id)
    .then(res => {
      this.setState({
        commentCount: res.data
      });
    })
    .catch(err => console.log(err));
  }

  render()
  {
    return (
      <div>
        <section className="blog-section">
          <div className="container">
            {this.state.blog.length > 0 ? // <----- here
              <div className="single-post no-sidebar">
                <div className="title-single-post">
                <a className="text-link" href="#"></a>
                <h1>{this.state.blog.title}</h1>
                <ul className="post-tags">
                  <li>{new Date(this.state.blog.createdAt).toDateString()}</li>
                  <li><a href="#">{this.state.commentCount.count} comments</a></li>
                </ul>
                </div>
                <div className="single-post-content">
                <img src={"../../" + this.state.blog.imageUrl} alt="" />
                <div className="post-content">
                  <div className="post-social">
                  <span>Share</span>
                  <ul className="share-post">
                      <li><a href="#" className="facebook"><i className="fa fa-facebook"></i></a></li>
                      <li><a href="#" className="twitter"><i className="fa fa-twitter"></i></a></li>
                      <li><a href="#" className="pinterest"><i className="fa fa-pinterest"></i></a></li>
                  </ul>
                  </div>
                  <BlogContent blog = {this.state.blog} />
                </div>
                <RelatedPosts category = {this.state.blog.category} />
                
                </div>
                <Comments />
              </div>
              : <h1>Loading</h1> // <----- here
          </div>
        </section>
    </div>
    );
  }
}

export default withRouter(SinglePost);

【讨论】:

  • 我明白你想说的话。但我仍然对如何实现它感到困惑。请多解释一点。那会更有帮助。
  • 如果你告诉我我需要这样做的功能/方法会更有帮助。
  • 这里的问题是,在页面加载时,您的页面正在渲染,并且内部组件被调用,但数据没有从 API 返回并设置为内部组件所需的状态,所以怎么办我做到了,在render 函数中我要求它检查数据是否存在于状态中,如果存在则继续渲染页面或显示加载消息....有多种方法可以做到...我展示了一种方式...few more ways
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多