Как найти источник «Инвариантного нарушения:« Ошибка Minified React # 31 »в React и исправить его? - PullRequest
0 голосов
/ 12 апреля 2019

После развертывания моего приложения на Heroku оно вылетает с сообщением InternalError: "too much recursion" затем Invariant Violation: "Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=InternalError%3A%20too%20much%20recursion&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings...., когда я пытаюсь получить доступ к домашней странице. Страница также ничего не отображает. Другие страницы работают нормально, но мне нужно отредактировать URL в браузере, чтобы получить к ним доступ. Я не вижу, что я делаю неправильно.

Если я попытаюсь отследить, сколько раз была выполнена выборка в componentDidMount, ошибка исчезнет. Я не вижу проблемы с вызванным также фумингом. Я проверил конечные полуколонны JS после тегов и убедился, что все компоненты возвращают действительный jsx.

Главная / index.js

import React, { Component } from "react";
import PageWrapper from "../PageWrapper";
import { connect } from "react-redux";
import { fetchHighlightedCourses } from "../../store/actions";

import AsyncWrapper from "../AsyncWrapper";
const AsyncCourseList = AsyncWrapper(() => import("./CourseList"));

class Home extends Component {
  componentDidMount() {
    const { highlightedCourses } = this.props;
    if (!Array.isArray(highlightedCourses) || highlightedCourses.length === 0)
      this.props.fetchHighlightedCourses();
  }

  _renderCourseList = () => {
    const { highlightedCourses } = this.props;
    console.log(highlightedCourses);
    if (Array.isArray(highlightedCourses) && highlightedCourses.length > 0)
      return <AsyncCourseList courses={highlightedCourses} />;
    return <div> </div>
  };

  render() {
    return (
      <PageWrapper title="Acceuil">
        {this._renderCourseList()}
      </PageWrapper>
    );
  }
}

const mapStateToProps = state => {
  return {
    highlightedCourses: state.explore.highlightedCourses
  };
};

export default connect(
  mapStateToProps,
  { fetchHighlightedCourses }
)(Home);

Главная / CourseList.js

import React from "react";
import classNames from "classnames";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";
import { Link as RouterLink } from "react-router-dom";
import Link from "@material-ui/core/Link";
import CourseCard from "./CourseCard";

const styles = theme => ({
  layout: {
    width: "auto",
    marginLeft: theme.spacing.unit * 3,
    marginRight: theme.spacing.unit * 3
  },
  cardGrid: {
    padding: `${theme.spacing.unit * 4}px 0`
  },
  catalogTitle: {
    color: theme.palette.text.secondary,
    marginBottom: theme.spacing.unit * 3
  },
  catalogLink: {
    marginTop: theme.spacing.unit * 3
  }
});

const CourseList = ({ classes, courses }) => {
  if (Array.isArray(courses))
    return (
      <div className={classNames(classes.layout, classes.cardGrid)}>
        <Typography variant="h6" className={classes.catalogTitle}>
          {"Que voulez-vous apprendre aujourd'hui?"}
        </Typography>
        <Grid container spacing={24}>
          {courses.map((course, index) => (
            <Grid item key={index}>
              <CourseCard course={course} />
            </Grid>
          ))}
        </Grid>
        <Typography variant="h6" className={classes.catalogLink}>
          <Link component={RouterLink} to={`/explore/classes`} underline="none">
            {"Voir plus des Cours >"}
          </Link>
        </Typography>
      </div>
    );
  return <div> </div>
};
export default withStyles(styles)(CourseList);

Главная / CourseCard.js

import React, { Component } from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardActions from "@material-ui/core/CardActions";
import MoreHoriz from "@material-ui/icons/MoreHoriz";
import CardContent from "@material-ui/core/CardContent";
import Grow from "@material-ui/core/Grow";
import CardMedia from "@material-ui/core/CardMedia";
import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import DefaultImage from "./default.jpg";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import { Link as RouterLink } from "react-router-dom";
import Link from "@material-ui/core/Link";

const styles = {
  card: {
    width: 190,
    height: "100%",
    display: "flex",
    flexDirection: "column"
  },
  media: {
    height: 90
  },
  courseTitle: {
    height: 65
    //overflowX: 'auto'
  },
  cardContent: {
    flexGrow: 1
  }
};

class CourseCard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      anchorEl: null
    };
  }
  handleMoreClick = event => {
    this.setState({ anchorEl: event.currentTarget });
  };

  handleMoreClose = () => {
    this.setState({ anchorEl: null });
  };

  render() {
    const { classes, course } = this.props;
    const { anchorEl } = this.state;
    return (
      <Grow in timeout={300}>
        <Card className={classes.card}>
          <CardActionArea>
            <Link
              component={RouterLink}
              to={`/explore/classe/${course._id}`}
              underline="none"
            >
              <CardMedia
                className={classes.media}
                image={course.img || DefaultImage}
                title="Default image"
              />
              <CardContent className={classes.cardContent}>
                <Typography
                  gutterBottom
                  variant="h6"
                  component="h6"
                  className={classes.courseTitle}
                >
                  {course.title}
                </Typography>
              </CardContent>
            </Link>
          </CardActionArea>
          <CardActions>
            <IconButton
              color="primary"
              aria-label="more_options"
              onClick={this.handleMoreClick}
            >
              <MoreHoriz />
            </IconButton>
            <Menu
              id="more_options"
              anchorEl={anchorEl}
              open={Boolean(anchorEl)}
              onClose={this.handleMoreClose}
            >
              <MenuItem onClick={this.handleMoreClose}>S'inscrire</MenuItem>
              <MenuItem onClick={this.handleMoreClose}>Détails</MenuItem>
            </Menu>
          </CardActions>
        </Card>
      </Grow>
    );
  }
}

CourseCard.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(CourseCard);

Следующее исправляет проблему, но я хотел бы знать, почему.

class Home extends Component {
state = { fetched: 0 };
  componentDidMount() {
    const { highlightedCourses } = this.props;
    if (
      (!Array.isArray(highlightedCourses) || highlightedCourses.length === 0) &&
      this.state.fetched < 3
    ) {
      this.setState(prev => ({ fetched: prev.fetched + 1 }));
      this.props.fetchHighlightedCourses();
    }
  }
...//the rest is the same
}

Вот действие

export const fetchHighlightedCourses = () => async dispatch => {
  try {
    dispatch({
      type: HIGHLIGHTED_COURSE_LOADING
    });

    const res = await axios.get(highlightedCourseURL);

    if (res.status === 200 && res.data.success) {
      return await dispatch({
        type: HIGHLIGHTED_COURSE_SUCCESS,
        payload: res.data.content
      });
    }
    return await dispatch({
      type: HIGHLIGHTED_COURSE_FAILLURE,
      payload: res.data.message
    });
  } catch (error) {
    let message;
    if (error.response && error.response.data && error.response.data.message)
      message = error.response.data.message;
    else message = "Erreur survenue lors du chargement de vos contacts";
    return await dispatch({
      type: HIGHLIGHTED_COURSE_FAILLURE,
      payload: message
    });
  } finally {
    return await dispatch({
      type: HIGHLIGHTED_COURSE_DONE
    });
  }
};

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...