反应TypeError:无法读取传递的道具时未定义的属性'map'

时间:2018-10-14 00:37:28

标签: javascript reactjs

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

enter image description here

组件是:

const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
const readline = require('readline');

exports.handler = async (event, context, callback) => {
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };
    const s3ReadStream = s3.getObject(params).createReadStream();

    const rl = readline.createInterface({
      input: s3ReadStream,
      terminal: false
    });

    let myReadPromise = new Promise((resolve, reject) => {

        rl.on('line', (line) => {
          console.log(`Line from file: ${line}`);
        });
        rl.on('error', () => {
            console.log('error');
        });
        rl.on('close', function () {
            console.log('closed');
            resolve();
        });
    });

    try { await myReadPromise; }
    catch(err) {
        console.log('an error has occurred');
    }

    console.log('done reading!');
};

和评论组件

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;

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

3 个答案:

答案 0 :(得分:0)

如果发生错误,您可以这样做:

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

使链接的承诺分解为undefined,并在comments状态下用作Comments。因此,您必须从catch中返回一个数组:

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

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

答案 1 :(得分:0)

另一种方法是检查它是否为数组,如果是,请检查其长度,然后执行.map。您已将注释初始化为空数组,因此我们无需检查它是否为数组,但是如果api响应接收到一个对象,则为了安全起见,它将把对象设置为注释,因此在这种情况下comment.length将不起作用最好检查它是否为数组。

以下更改将起作用

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

答案 2 :(得分:-1)

注释组件第一次呈现时,没有响应,因此注释未定义。

    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;