【问题标题】:React TypeError: Cannot read property 'map' of undefined on passing propsReact TypeError:无法在传递道具时读取未定义的属性“地图”
【发布时间】:2019-03-18 19:21:51
【问题描述】:

从 post 组件获取 cmets 数组并将其传递给 cmets 组件后 日志开始在下面的屏幕截图中显示错误

组件是:

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

import Comments from "../components/comments";

    class Article extends Component {
        constructor(props) {
            super(props);

            this.state = {
                title: "",
                error: "",
                comment: ""
            };
        }

        componentDidMount() {

            this.getComments();
        }


        getComments = () => {
            const {
                match: { params }
            } = this.props;

            return axios
                .get(`/articles/${params.id}/comments`, {
                    headers: {
                        Accept: "application/json",
                        "Content-Type": "application/json",

                    }
                })
                .then(response => {
                    return response.json();
                })
                .then(response => this.setState({ comments: response.comments }))
                .catch(error =>
                    this.setState({
                        error
                    })
                );
        };



        render() {
            return (
                <div>
                    {this.state.title}
                    <div>
                        <h2>Comments</h2>
                        <Comments
                            getComments={this.getComments}

                        />
                    </div>

                </div>
            );
        }
    }

    export default Article;

和评论组件

import React, { Component } from "react";
import PropTypes from "prop-types";
import Comment from "./comment";
import axios from "axios";

import Article from "../screens/article";

class Comments extends Component {
  constructor(props) {
    super(props);
    this.state = {
      comments: [],

      comment: "",
      error: ""
    };

    this.load = this.load.bind(this);

    this.comment = this.comment.bind(this);
  }

  componentDidMount() {
    this.load();
  }

  load() {
    return this.props.getComments().then(comments => {
      this.setState({ comments });

      return comments;
    });
  }

  comment() {
    return this.props.submitComment().then(comment => {
      this.setState({ comment }).then(this.load);
    });
  }

  render() {

    const { comments } = this.state;

    return (
      <div>
        {comments.map(comment => (
          <Comment key={comment.id} commment={comment} />
        ))}
      </div>
    );
  }
}



export default Comments;

所以,我尝试通过 props 传递它,并在 cmets 组件上设置状态。 而不是只使用 cmets.map 我尝试使用 this.state 但在日志中显示相同的错误。 那么,有人想澄清这种问题吗? 使用 react 时似乎很常见的问题。

【问题讨论】:

  • 嗨@JonasWilms,是的。应该包含 cmets 数组

标签: javascript reactjs


【解决方案1】:

如果发生错误,请执行以下操作:

  .catch(error =>  this.setState({ error  }) );

这使得链式承诺解析为undefined,并在Comments 状态下用作comments。所以你必须从 catch 中返回一个数组:

 .catch(error => {
   this.setState({ error });
   return [];
 });

此外,如果父状态包含错误,则根本不渲染 Comments 子是有意义的。

【讨论】:

  • 那么,不设置错误会导致链式事件导致设置cmets时出现未定义错误?
  • @lula yup catch 是为了让承诺链“回到正轨”,所以你应该从中返回一些有用的东西(一个数组)
  • 啊,非常感谢乔纳斯!我知道我错过了什么。
【解决方案2】:

另一种方法是检查它是否是一个数组,如果是,检查它的长度,然后做.map。您已将 cmets 初始化为空数组,因此我们不需要检查它是否是一个数组,但如果 api 响应接收到一个对象,那么它会将对象设置为 cmets,因此在这种情况下 cmets.length 将不起作用所以看看是不是数组就好了。

下面的改变会起作用

  <div>
    {Array.isArray(comments) && comments.length>0 && comments.map(comment => (
      <Comment key={comment.id} commment={comment} />
    ))}
  </div>

【讨论】:

    【解决方案3】:

    cmets 组件第一次渲染时还没有响应,所以 cmets 是未定义的。

        import React, { Component } from "react";
    import PropTypes from "prop-types";
    import Comment from "./comment";
    import axios from "axios";
    
    import Article from "../screens/article";
    
    class Comments extends Component {
      constructor(props) {
        super(props);
        this.state = {
          comments: [],
    
          comment: "",
          error: ""
        };
    
        this.load = this.load.bind(this);
    
        this.comment = this.comment.bind(this);
      }
    
      componentDidMount() {
        this.load();
      }
    
      load() {
        return this.props.getComments().then(comments => {
          this.setState({ comments });
    
          return comments;
        });
      }
    
      comment() {
        return this.props.submitComment().then(comment => {
          this.setState({ comment }).then(this.load);
        });
      }
    
      render() {
    
        const { comments } = this.state;
    
        if (!comments) return <p>No comments Available</p>;
    
        return (
          <div>
            {comments.map(comment => (
              <Comment key={comment.id} commment={comment} />
            ))}
          </div>
        );
      }
    }
    
    
    
    export default Comments;
    

    【讨论】:

    • Tarek 谢谢,组件之间的时间有问题吗?
    • 不客气。这不是一个正常的问题,您只需要考虑即可。现在正常吗?
    • Tarek,谢谢,是的,不是的,是的,不显示错误,但也没有显示 cmets。我没有否决你的回答。并感谢您的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 2017-03-26
    • 2021-09-09
    • 2020-09-16
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多