尝试打印出具有数组的对象时出现错误

时间:2018-08-08 23:12:45

标签: reactjs axios react-router-dom

我已经尝试过对此处列出的问题进行其他回答,但它们不起作用。我在做什么不同?

我有一个应用程序,我想在其中列出与之相关的评论列表/评论数组的主题。当用户单击“添加主题”链接时,用户将看到一个随机主题,该主题带有与之相关的过去评论,并且有机会添加新评论。我可以打印出主题,但不能打印出评论。我什至可以在控制台中打印出注释,但不能在页面上打印。

该错误表明注释未定义。我在做什么错了?

代码如下:

topic.js

import React, { Component } from "react";
import axios from "axios";
import { withRouter } from "react-router-dom";
import { createComment, listTopicWithComments } from "../util/APIUtils";
import "./Topic.css";
import TopicComp from "../components/TopicComp";
import { Form, Input, Button, Icon, Select, Col, notification } from "antd";
const URL = "http://localhost:8080/api/auth/randomtopic";
const URL2 = "http://localhost:8080/api/auth/topic/";
const Option = Select.Option;
const FormItem = Form.Item;
const { TextArea } = Input;

class Topic extends Component {
  constructor(props) {
    super(props);
    this.state = {
      topic: {},
      comment: {
        text: ""
      }
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.isFormInvalid = this.isFormInvalid.bind(this);
    this.handleCommentChange = this.handleCommentChange.bind(this);
    //this.listTopicWithComments=this.listTopicWithComments.bind(this);
  }
  handleSubmit(event) {
    event.preventDefault();
    const commentData = this.state.comment.text;
    const commentTopicid = this.state.topic.id;
    console.log("commentdata:", commentData);
    console.log("topicid: ", commentTopicid);

    createComment(commentData, commentTopicid)
      .then(response => {
        console.log("response comment: ", response.data);
        this.props.history.push("/");
      })
      .catch(error => {
        if (error.status === 401) {
          this.props.handleLogout(
            "/login",
            "error",
            "You have been logged out. Please login and choose randome topic."
          );
        } else {
          notification.error({
            message: "Social-J App",
            description: error.message || "Sorry, something went wrong."
          });
        }
      });
    listTopicWithComments(commentTopicid).then(response => {
      console.log("topic comment", response.data);
      this.props.history.push("/");
    });
  }

  validateComment = commentText => {
    if (commentText.length === 0) {
      return {
        validateStatus: "error",
        errorMsg: "Please enter your comment!"
      };
    } else if (commentText.length > 150) {
      return {
        validateStatus: "error",
        errorMsg: `Comment is too long (Maximum 150 characters 
        allowed)`
      };
    } else {
      return {
        validateStatus: "success",
        errorMsg: null
      };
    }
  };

  handleCommentChange(event) {
    const value = event.target.value;
    this.setState({
      comment: {
        text: value,
        ...this.validateComment(value)
      }
    });
  }

  componentDidMount() {
    if (this.props.isAuthenticated) {
      axios
        .get(URL)
        .then(response => {
          console.log("response", response.data);
          this.setState({ topic: response.data });
        })
        .catch(err => {
          console.log(err);
        });
    }
  }

  isFormInvalid() {
    if (this.state.comment.validateStatus !== "success") {
      return true;
    }
  }

  render() {
    //console.log("URL used: ",URL);
    //console.log("new topic",this.state.topic.id);
    //console.log("new topic",this.state.topic.topic);

    const topicId = this.state.topic.id;
    const uDate = this.state.topic.expirationDateTime;
    const oldComments = this.state.topic.comments;
    console.log("topicid: ", topicId);
    console.log("date: ", uDate);
    console.log("oldcomments: ", oldComments);

    //return nComment;
    return (
      <div className="new-comment-container">
        <h1 className="page-title">{this.state.topic.topic}</h1>
        <div>
          {this.state.topic.comments.map(comment => {
            return <div key={comment.id}>{comment.comment}</div>;
          })}
        </div>
        <div className="new-comment-content">
          <Form
            onSubmit={this.handleSubmit}
            className="create- 
                  comment-form"
          >
            <FormItem
              validateStatus={this.state.comment.validateStatus}
              help={this.state.comment.errorMsg}
              className="comment-form-row"
            >
              <TextArea
                placeholder="Enter comment"
                style={{
                  fontSize: "16px"
                }}
                autosize={{ minRows: 3, maxRows: 6 }}
                name="comment"
                value={this.state.comment.text}
                onChange={this.handleCommentChange}
              />
            </FormItem>
            <FormItem className="comment-form-row">
              <Button
                type="primary"
                htmlType="submit"
                size="large"
                disabled={this.isFormInvalid()}
                className="create-comment-form-button"
              >
                Add Comment
              </Button>
            </FormItem>
          </Form>
        </div>
        <div>hi</div>
      </div>
    );
  }
}
export default withRouter(Topic);

这是错误。 TypeError:

  

this.state.topic.comments是未定义的渲染   client / src / components / Topic.js:134

         131 |  <div className="new-comment-container">
         132 |  <h1 className="page-title">{this.state.topic.topic}</h1>
         133 |  <div>
       > 134 |     {this.state.topic.comments.map(comment =>{
         135 |         return <div key={comment.id}>
         136 |         {comment.comment}
         137 | </div>

1 个答案:

答案 0 :(得分:2)

您正在尝试加载this.state.topic.comments之前使用topic

您可以例如首先将主题设置为null,然后从渲染返回null,直到它被设置为止。

示例

class Topic extends Component {
  constructor(props) {
    super(props);
    this.state = {
      topic: null,
      comment: {
        text: ""
      }
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.isFormInvalid = this.isFormInvalid.bind(this);
    this.handleCommentChange = this.handleCommentChange.bind(this);
  }

  render() {
    const { topic } = this.state;

    if (topic === null) {
      return null;
    }

    // ...
  }
}