类型错误:无法在 Va 读取未定义的属性“长度”

时间:2021-06-16 07:43:51

标签: reactjs react-redux

在我的本地系统上,在实时服务器上一切正常,但存在一些长度问题,请帮忙..

我尝试过使用 useSelector(),没有 mapDispatchToProps、mapStateToProps、Async 调用,但仍然存在同样的问题。

在 index.js 文件中

import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
import { useSelector, useDispatch, connect } from "react-redux";
import {batchActions} from 'redux-batched-actions';


import "fontsource-roboto";
import { fade, withStyles } from "@material-ui/core/styles";
import { Header } from "../../components";
import Typography from "@material-ui/core/Typography";
import Container from "@material-ui/core/Container";
import Box from "@material-ui/core/Box";
import TopCard from "./topCards";
import GraphCards from "./graphCards";
import ClassJoinCard from "../yourClasses/common/ClassJoinCard";
import ResourceCard from "./ResourceCard";
import { Fonts, Color } from "../../theme/index";
import Carousel from "react-multi-carousel";
import moment from "moment";
import "react-multi-carousel/lib/styles.css";

import { getDashboardData } from "../../redux/actions/userActions";

// import { getClassesList } from "../../redux/actions/classesActions";
// import { getStudentClassList, getTopPerformedStudent } from "../../redux/actions/studentActions";
// import { getTopPerformedTeacher } from "../../redux/actions/teacherActions";

// import { newLessionPlan } from "../../redux/actions/lessionPlanActions";
// import { newResources } from "../../redux/actions/resourceActions";

const styles = (theme) => ({
  container: {
    alignSelf: "flex-end",
    paddingLeft: 250,
    paddingTop: 70,
    paddingBottom: 20,
  },
  root: {
    maxWidth: 345,
    marginTop: 10,
    marginRight: 10,
  },
  media: {
    height: 140,
  },
  mainHeading: {
    fontSize: "20px",
    fontFamily: Fonts.Medium,
  },
  bigHeading: {
    fontSize: "1.5rem",
    fontFamily: Fonts.Medium,
    opacity: ".8",
  },
  smallGrayTitle: {
    color: "rgba(0,0,0,1)",
    fontSize: "12px",
    fontFamily: Fonts.Medium,
    opacity: "0.5",
  },
  smallerTitle: {
    fontSize: "12px",
    fontFamily: Fonts.Regular,
    textTransform: "uppercase",
    // opacity: ".6",
    padding: "5px 0 0 0",
    margin: "0",
  },
  dateTitle: {
    color: Color.textBlack,
    fontSize: "12px",
    fontFamily: Fonts.Regular,
    textAlign: "center",
    opacity: ".6",
    padding: "0",
    margin: "0",
    marginBottom: "3px",
  },
  centerFlex: {
    flexDirection: "row",     /* make main axis horizontal (default setting) */
    justifyContent: "center", /* center items horizontally, in this case */
    alignItems: "center"
  }
});

const TeacherClassListing = ({props, openClass, authUser}) => {
  const { dashboardData } = props;
  // const classList = useSelector((store) => store.classes.list);
  // const dispatch = useDispatch();

  // useEffect(() =>  {
  //     getClassesList()
  // }, [])

  return (
    <>
      {
        console.log("classList dashboardData.classes", dashboardData.classes)
      }
      {
        ((dashboardData) && (dashboardData.classes) && (dashboardData.classes.length > 0)) ? (
          dashboardData.classes.map((v, i) => {
            return (
              <ClassJoinCard
                data={v}
                key={i}
                openClass={openClass}
              />
            );
          })
        ) : ('No Class found')
      }
    </>
  )
}

const StudentClassListing = ({props, openClass, authUser}) => {
  const {dashboardData} = props
  // const classList = useSelector((store) => store.students.classList);

  // const dispatch = useDispatch();
  
  // useEffect(() =>  {
  //     getStudentClassList()
  // }, [])

  return (
    <>
      {
        console.log("classList dashboardData.studentsClasses", dashboardData.studentsClasses)
      }
      {
        ((dashboardData) && (dashboardData.studentsClasses) && (dashboardData.studentsClasses.length > 0)) ? (
          dashboardData.studentsClasses.map((v, i) => {
            return (
              <ClassJoinCard
                data={v}
                key={i}
                openClass={openClass}
              />
            );
          })
        ) : ('No Class found')
      }
    </>
  )
}

const Resource = ({props, authUser, actionPage}) => {
  const {dashboardData} = props


  // const newResourcesList = useSelector((store) => store.resource.new);
  // const dispatch = useDispatch();

  // useEffect(() =>  {
  //     newResources()
  // }, [])

  return (
    <>
      {
        console.log("dashboardData.resources", dashboardData.resources)
      }
      {
        ((dashboardData) && (dashboardData.resources) && (dashboardData.resources.length > 0)) ? (
          dashboardData.resources.map((v, i) => {
            return (
              <ResourceCard
                actionPage={actionPage}
                data={v}
                key={i}
              />
            );
          })
        ) : ('No Class found')
      }
    </>
  )
}

const LessonPlans = ({props, authUser, actionPage}) => {
  const {dashboardData} = props

  // const newLessionPlanList = useSelector((store) => store.lessionPlan.new);
  // const dispatch = useDispatch();
  
  // useEffect(() =>  {
  //     newLessionPlan()
  // }, [])

  return (
    <>
      {
        console.log("dashboardData.lessonPlans", dashboardData.lessonPlans)
      }
      {
        ((dashboardData) && (dashboardData.lessonPlans) && (dashboardData.lessonPlans.length > 0)) ? (
          dashboardData.lessonPlans.map((v, i) => {
            return (
              <ResourceCard
                actionPage={actionPage}
                data={v}
                key={i}
              />
            );
          })
        ) : ('No Class found')
      }
    </>
  )
}

const Dashboard = (props) => {
  const { classes, history, getDashboardData, dashboardData } = props;
  // const dispatch = useDispatch();

  const authUser = useSelector((store) => store.auth.user);
  // const store = useSelector((store) => store)

  // const [topRatedTeachers, setTopRatedTeachers] = useState([]);
  // const [topRatedStudents, setTopRatedStudents] = useState([]);

  // const topRated = useSelector((store) => store.users.top);
  // const topRatedStudents = useSelector((store) => store.students.topRated);

  useEffect(() => {
    getDashboardData()
    // dispatch( getTopRatedList() )
    // dispatch( getTopPerformedStudent() )
  }, [])
  
  // useEffect(() => {
  //   setTopRatedTeachers(store.teachers.topRated)
  //   setTopRatedStudents(store.students.topRated)
  // }, [store])

  const openClass = () => {
    history.push("your-classes");
  }

  const openResourcePage = () => {
    history.push("resources");
  }

  const openLessionPlanPage = () => {
    history.push("lesson-plan");
  }

  const generateGreetings = () => {
    var currentHour = moment().format("HH");
    // var currentHour = 22;
  
    if (currentHour >= 3 && currentHour < 12) {
        return "Good Morning";
    } else if (currentHour >= 12 && currentHour < 15) {
        return "Good Afternoon";
    }   else if (currentHour >= 15 && currentHour < 20) {
        return "Good Evening";
    } else {
        return (authUser.user_type == 1) ? 'Hello Teacher' : 'Hello Student'
    }
  }
    
  return (
    <>
      <Header history={history} />
      <Container maxWidth="xl" className={classes.container}>
        <Box flexWrap="wrap" p={2} m={0} bgcolor="background.paper">
          <Typography
            variant="h5"
            component="h5"
            className={classes.bigHeading}
            style={{ marginBottom: "-5px" }}
          >
            { generateGreetings() }, { (authUser.first_name) ? authUser.first_name : '' }.{" "}
          </Typography>
          <Typography
            variant="caption"
            color="primary"
            className={classes.smallGrayTitle}
          >
            { moment().format("dddd, DD MMMM YYYY") }, Hope you have a great day.
          </Typography>

          <Box paddingTop={1} bgcolor="background.paper">
            <Typography
              variant="h5"
              component="h5"
              className={classes.mainHeading}
              style={{ marginBottom: "-5px" }}
            >
              Top Performing Teachers
            </Typography>
            <Typography
              variant="caption"
              color="primary"
              className={classes.smallGrayTitle}
            >
              Top 3 performers each month win 300, 200, 100 rmb
            </Typography>
            <Box
              display="flex"
              flexDirection="row"
              flexWrap="wrap"
              paddingTop={0}
              bgcolor="background.paper"
              className={classes.centerFlex}
            >
              {
                console.log("topRated.teachers dashboardData.teachers", dashboardData.teachers)
              }
              {
                ((dashboardData) && (dashboardData.teachers) && (dashboardData.teachers.length > 0)) ? dashboardData.teachers.map( (value, index) => {
                  return <>
                    <TopCard authUser={authUser} value={value} />
                  </>
                } ) : ('')
              }
            </Box>
          </Box>

          <Box paddingTop={1} bgcolor="background.paper">
            <Typography
              variant="h5"
              component="h5"
              className={classes.mainHeading}
              style={{ marginBottom: "-5px" }}
            >
              Top Performing Students
            </Typography>
            <Typography
              variant="caption"
              color="primary"
              className={classes.smallGrayTitle}
            >
              Top 3 performers each month win 300, 200, 100 rmb
            </Typography>
            <Box
              display="flex"
              flexDirection="row"
              flexWrap="wrap"
              paddingTop={0}
              bgcolor="background.paper"
              className={classes.centerFlex}
            >
              {
                console.log("topRated.students dashboardData.students", dashboardData.students)
              }
              {
                ((dashboardData) && (dashboardData.students) && (dashboardData.students.length > 0)) ? dashboardData.students.map( (value, index) => {
                  return <>
                    <TopCard authUser={authUser} value={value} />
                  </>
                } ) : ('')
              }
            </Box>
          </Box>

          <Box paddingTop={2} bgcolor="background.paper">
            <Typography
              variant="h5"
              component="h5"
              className={classes.mainHeading}
              style={{ marginBottom: "-5px" }}
            >
              My Classes
            </Typography>
            <Typography
              variant="caption"
              color="primary"
              className={classes.smallGrayTitle}
            >
              Respond so you can track of your assignments.
            </Typography>
            <Box
              display="flex"
              flexDirection="row"
              flexWrap="wrap"
              paddingTop={0}
              bgcolor="background.paper"
              className={classes.centerFlex}
            >
              {
                ( authUser.user_type == 1 ) ? (
                  <>
                    <TeacherClassListing props={props} openClass={openClass} authUser={authUser} />
                  </>
                ) : (
                  <StudentClassListing props={props} openClass={openClass} authUser={authUser} />
                )
              }
            </Box>
          </Box>

          <Box paddingTop={4} bgcolor="background.paper">
            <Typography
              variant="h5"
              component="h5"
              className={classes.mainHeading}
              style={{ marginBottom: "-5px" }}
            >
              {
                ( authUser.user_type == 1 ) ? (
                  <>
                    {"New Resouces Uploaded"}
                  </>
                ) : (
                  <>
                    {"New Lesson plans Uploaded"}
                  </>
                )
              }
            </Typography>
            <Typography
              variant="caption"
              color="primary"
              className={classes.smallGrayTitle}
            >
              Respond so you can track of your assignments.
            </Typography>
            <Box
              display="flex"
              flexDirection="row"
              flexWrap="wrap"
              paddingTop={0}
              bgcolor="background.paper"
              className={classes.centerFlex}
            >
              {
                ( authUser.user_type == 2 ) ? (
                  <>
                    <Resource props={props} authUser={authUser} actionPage={openResourcePage} />
                  </>
                ) : (
                  <LessonPlans props={props} authUser={authUser} actionPage={openLessionPlanPage} />
                )
              }
            </Box>
          </Box>
        </Box>
      </Container>
    </>
  );
}

const mapDispatchToProps = dispatch => {
  return {
    getDashboardData: () => dispatch( getDashboardData() ),
    // getClassesList: () => dispatch( getClassesList() ),
    // getStudentClassList: () => dispatch( getStudentClassList() ),
    // newResources: () => dispatch( newResources() ),
    // newLessionPlan: () => dispatch( newLessionPlan() )
  }
}

const mapStateToProps = state => {
  return {
    dashboardData: state.users.dashboard,
    // classList: state.classes.list,
    // studentClassList: state.students.classList,
    // newResourcesList: state.resource.new,
    // newLessionPlanList: state.lessionPlan.new,
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles, { withTheme: true })(Dashboard));

我将它们作为 userActions.js 文件中的操作

export function getDashboardData() {
    return  async dispatch => {
        // try {
            try {
            const response = await axios.get(Const.BASE_URL + 'user/dashboard', axiosOptions(localStorage.userToken));
            dispatch({
                type: 'USERS_TOP',
                payload: response.data.output,
            });
            return await Promise.resolve({
                type: 'success',
                payload: response.data.output,
            });
        } catch (error) {
            dispatch({
                type: 'USERS_ERROR',
                payload: error,
            });
            return await Promise.resolve({
                type: 'error',
                payload: error,
            });
        }
    }
}

在减速器中

const initialState = {
    dashboard : {
        teachers: [],
        students: [],
        classes: [],
        studentsClasses: [],
        lessonPlans: [],
        resources: [],
    },
    error : "",
}

function users ( state = initialState, action ) {
    switch ( action.type ) {
        case 'USERS_TOP' :
            return { ...state, dashboard: action.payload };
        case 'USERS_ERROR' :
            return { ...state, error: action.payload };
        default :
            return state
    }
}

export default users

控制台日志..

index.js:311 topRated.teachers dashboardData.teachers []
index.js:348 topRated.students dashboardData.students []
index.js:98 classList dashboardData.classes []
index.js:195 dashboardData.lessonPlans []
2.473adc03.chunk.js:2  action LOGIN_SUCCESS @ 12:42:42.805
2.473adc03.chunk.js:2  prev state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
2.473adc03.chunk.js:2  action     {type: "LOGIN_SUCCESS", payload: {…}}
2.473adc03.chunk.js:2  next state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
AccountDetails.js:240 response {type: "success", payload: {…}}
2.473adc03.chunk.js:2  action SET_USER_REDIRECT @ 12:42:42.888
2.473adc03.chunk.js:2  prev state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
2.473adc03.chunk.js:2  action     {type: "SET_USER_REDIRECT", payload: "/"}
2.473adc03.chunk.js:2  next state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
index.js:311 topRated.teachers dashboardData.teachers []
index.js:348 topRated.students dashboardData.students []
index.js:98 classList dashboardData.classes []
index.js:195 dashboardData.lessonPlans []
index.js:311 topRated.teachers dashboardData.teachers (3) [{…}, {…}, {…}]
index.js:348 topRated.students dashboardData.students (3) [{…}, {…}, {…}]
index.js:98 classList dashboardData.classes (3) [{…}, {…}, {…}]
index.js:195 dashboardData.lessonPlans (3) [{…}, {…}, {…}]
2.473adc03.chunk.js:2  action USERS_TOP @ 12:42:43.332
2.473adc03.chunk.js:2  prev state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
2.473adc03.chunk.js:2  action     {type: "USERS_TOP", payload: {…}}
2.473adc03.chunk.js:2  next state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
6Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure element '<URL>'. This request was automatically upgraded to HTTPS, For more information see <URL>
index.js:311 topRated.teachers dashboardData.teachers (3) [{…}, {…}, {…}]
index.js:348 topRated.students dashboardData.students (3) [{…}, {…}, {…}]
index.js:98 classList dashboardData.classes (3) [{…}, {…}, {…}]
index.js:195 dashboardData.lessonPlans (3) [{…}, {…}, {…}]
22.473adc03.chunk.js:2 TypeError: Cannot read property 'length' of undefined
    at Va (2.473adc03.chunk.js:2)
    at no (2.473adc03.chunk.js:2)
    at Object.ao [as useEffect] (2.473adc03.chunk.js:2)
    at Object.t.useEffect (2.473adc03.chunk.js:2)
    at x (2.473adc03.chunk.js:2)
    at k (2.473adc03.chunk.js:2)
    at 2.473adc03.chunk.js:2
    at Ya (2.473adc03.chunk.js:2)
    at Mo (2.473adc03.chunk.js:2)
    at gs (2.473adc03.chunk.js:2)
    at cl (2.473adc03.chunk.js:2)
    at sl (2.473adc03.chunk.js:2)
    at $s (2.473adc03.chunk.js:2)
    at 2.473adc03.chunk.js:2
    at t.unstable_runWithPriority (2.473adc03.chunk.js:2)
    at Hi (2.473adc03.chunk.js:2)
es @ 2.473adc03.chunk.js:2
r.callback @ 2.473adc03.chunk.js:2
da @ 2.473adc03.chunk.js:2
as @ 2.473adc03.chunk.js:2
hl @ 2.473adc03.chunk.js:2
t.unstable_runWithPriority @ 2.473adc03.chunk.js:2
Hi @ 2.473adc03.chunk.js:2
fl @ 2.473adc03.chunk.js:2
$s @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
t.unstable_runWithPriority @ 2.473adc03.chunk.js:2
Hi @ 2.473adc03.chunk.js:2
Vi @ 2.473adc03.chunk.js:2
Wi @ 2.473adc03.chunk.js:2
el @ 2.473adc03.chunk.js:2
notify @ 2.473adc03.chunk.js:2
t.notifyNestedSubs @ 2.473adc03.chunk.js:2
t.handleChangeWrapper @ 2.473adc03.chunk.js:2
v @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
dispatch @ 2.473adc03.chunk.js:2
(anonymous) @ userActions.js:38
c @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
n @ 2.473adc03.chunk.js:2
s @ 2.473adc03.chunk.js:2
Promise.then (async)
n @ 2.473adc03.chunk.js:2
s @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ userActions.js:34
(anonymous) @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
getDashboardData @ index.js:449
(anonymous) @ index.js:228
is @ 2.473adc03.chunk.js:2
gl @ 2.473adc03.chunk.js:2
t.unstable_runWithPriority @ 2.473adc03.chunk.js:2
Hi @ 2.473adc03.chunk.js:2
ml @ 2.473adc03.chunk.js:2
$s @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
t.unstable_runWithPriority @ 2.473adc03.chunk.js:2
Hi @ 2.473adc03.chunk.js:2
Vi @ 2.473adc03.chunk.js:2
Wi @ 2.473adc03.chunk.js:2
Xs @ 2.473adc03.chunk.js:2
enqueueSetState @ 2.473adc03.chunk.js:2
w.setState @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
n @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
notifyListeners @ 2.473adc03.chunk.js:2
E @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
confirmTransitionTo @ 2.473adc03.chunk.js:2
push @ 2.473adc03.chunk.js:2
(anonymous) @ AccountDetails.js:244
Promise.then (async)
(anonymous) @ AccountDetails.js:239
s @ 2.473adc03.chunk.js:2
h @ 2.473adc03.chunk.js:2
(anonymous) @ 2.473adc03.chunk.js:2
v @ 2.473adc03.chunk.js:2
ot @ 2.473adc03.chunk.js:2
it @ 2.473adc03.chunk.js:2
st @ 2.473adc03.chunk.js:2
ht @ 2.473adc03.chunk.js:2
B @ 2.473adc03.chunk.js:2
z @ 2.473adc03.chunk.js:2
Qt @ 2.473adc03.chunk.js:2
Jt @ 2.473adc03.chunk.js:2
t.unstable_runWithPriority @ 2.473adc03.chunk.js:2
Hi @ 2.473adc03.chunk.js:2
D @ 2.473adc03.chunk.js:2
Kt @ 2.473adc03.chunk.js:2
Show 31 more frames
2.473adc03.chunk.js:2  action USERS_TOP @ 12:42:43.742
2.473adc03.chunk.js:2  action USERS_ERROR @ 12:42:43.765
2.473adc03.chunk.js:2  prev state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}
2.473adc03.chunk.js:2  action     {type: "USERS_ERROR", payload: TypeError: Cannot read property 'length' of undefined
    at Va (https://irevu.org/static/js/2.473a…}
2.473adc03.chunk.js:2  next state {auth: {…}, upload: {…}, classes: {…}, university: {…}, course: {…}, …}

我有什么不正确的?

1 个答案:

答案 0 :(得分:0)

无论您在哪里检查长度,初始值都不是数组,这就是为什么要破坏。

在任何地方进行空检查。

示例:

dashboardData?.studentsClasses?.length > 0

(dashboardData?.teachers?.length > 0)

任何地方,

<块引用>

使用可选链 - 你在对象中有你的数组,你应该把空检查放进去 避免此类问题。