Ошибка типа: comments.map не является функцией react js

#javascript #reactjs #web

#javascript #reactjs #веб

Вопрос:

Я получил сообщение об ошибке при выборе объекта, в настоящее время файлы комментариев хранятся в другом файле, и я обращаюсь к нему в этом файле, но я получил сообщение об ошибке

Ошибка типа: comments.map не является функцией

мой код:

 import React from "react";
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from "reactstrap";

function RenderDish({ dish }) {
  if (dish != null) {
    return (
      <div className="col-12 col-md-5 m-1">
        <Card>
          <CardImg width="100%" object src={dish.image} alt={dish.name}></CardImg>
          <CardBody>
            <CardTitle>{dish.name}</CardTitle>
            <CardText>{dish.description}</CardText>
          </CardBody>
        </Card>
      </div>
    );
  } else {
    return <div></div>;
  }
}
function RenderComments(comments) {
  if (comments != null) {
    const commentsList = comments.map((Comment) => {
      return (
        <div className="container">
          <li key={Comment.id}>
            <p>{Comment.Comment}</p>
            <p>
              -- {Comment.author},
              {new Intl.DateTimeFormat("en-US", { year: "numeric", month: "short", day: "2-digit" }).format(new Date(Date.parse(Comment.id)))}
            </p>
          </li>
        </div>
      );
    });
    return (
      <div className="col-12 col-md-5 m-1">
        <h3>Comments</h3>
        <ul className="list-unstyled">{commentsList}</ul>
      </div>
    );
  } else {
    return <div></div>;
  }
}
const DishDetail = (props) => {
  console.log("Dishdetail Component render invoked");
  if (props.dish != null) {
    return (
      <div className="row">
        <RenderDish dish={props.dish} />
        <RenderComments comments={props.dish.comments} />
      </div>
    );
  } else {
    return <div></div>;
  }
};

export default DishDetail;
  

Комментарии:

1. Является ли тип ваших комментариев массивом? чтобы использовать комментарии к карте, это должен быть массив, а не объект. запишите в консоль свои комментарии и проверьте тип.

2. Если ваш комментарий имеет правильный тип, похоже, что к моменту вызова рендеринга ваш реквизит не готов к рендерингу. вместо использования if(comments === null) { .... } else { ... } вы должны попытаться отобразить компонент, когда у вас есть реквизиты. Вам нужно сделать что-то вроде return (<div className="col-12 col-md-5 m-1"><h3>Comments</h3><ul className="list-unstyled">{ /* do your check and return here */}</ul></div>) ;

3. Убедитесь, что комментарий представляет собой массив

4. props.dish.comments, похоже, не является массивом

Ответ №1:

Вы передаете prop и сопоставляете prop вместо доступа к нему:

 <RenderComments comments={props.dish.comments} />

// Not RenderComments(comments)
function RenderComments(props) {
  ...
  props.comments.map(...)
}
  

Ответ №2:

Я получил ту же ошибку.

В моем случае один элемент массива был передан ошибочно, выбрав индекс 0 вместо полного массива в главном компоненте.

comments={this.state.comments.filter((comment) => comment.dishId === parseInt(match.params.dishId, 10))[0]} в основном компоненте.

Исправленная версия:

 const DishWithId = ({ match }) => {
        return (
            <DishDetail dish={this.state.dishes.filter((dish) => dish.id === parseInt(match.params.dishId, 10))[0]}
                comments={this.state.comments.filter((comment) => comment.dishId === parseInt(match.params.dishId, 10))} />
        );
    }
  

Ответ №3:

Я прошу прощения, что этот ответ является излишним.

Все, что вы передаете в like comment={comment} , будет частью реквизита как объекта, поэтому вам нужно деконструировать комментарий из него.

Вам также не нужно возвращать пустые div во время условного рендеринга. Возврат ничего не совпадает.

Кроме того, value != null этого недостаточно. Если значение имеет значение любого другого типа falsey, ваше приложение все равно выйдет из строя, так !value что это намного безопаснее.

Если вы собираетесь условно отображать inline, его гораздо проще использовать amp;amp; или использовать троичный ? : вместо стандартного if .

 import React from "react";
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from "reactstrap";

const RenderDish = ({ dish }) => (
  dish amp;amp; (
    <div className="col-12 col-md-5 m-1">
      <Card>
        <CardImg width="100%" object src={dish.image} alt={dish.name}></CardImg>
        <CardBody>
          <CardTitle>{dish.name}</CardTitle>
          <CardText>{dish.description}</CardText>
        </CardBody>
      </Card>
    </div>
  )
);

const RenderComments = ({ comments }) => (
  comments amp;amp; (
    <div className="col-12 col-md-5 m-1">
      <h3>Comments</h3>
      <ul className="list-unstyled">{
        comments.map(comment => (
          <div className="container">
            <li key={comment.id}>
              <p>{comment.comment}</p>
              <p>
                -- {comment.author},
                {new Intl.DateTimeFormat("en-US", {
                  year: "numeric",
                  month: "short",
                  day: "2-digit"
                }).format(new Date(Date.parse(comment.id)))}
              </p>
            </li>
          </div>
        ))
      }</ul>
    </div>
  )
);

const DishDetail = ({ dish }) => (
  dish amp;amp; (
    <div className="row">
      <RenderDish dish={dish} />
      <RenderComments comments={dish.comments} />
    </div>
  )
);

export default DishDetail;