“未捕获的TypeError:在浏览器

时间:2018-03-15 20:46:58

标签: reactjs undefined uncaught-typeerror

我已经使用react js编写了部分代码来开发一个网站。

我在加载localhost / events.html页面时看到网页中缺少事件类数据。

我只能在浏览同一网站的不同页面后才能在events.html中看到事件类数据。但不是第一次点击该页面。

以下是chrome开发人员工具中的堆栈跟踪。我也面临着同样的问题。

Uncaught TypeError: Cannot read property 'map' of undefined
at EventClasses.render (Events.js:24)
at ReactCompositeComponent.js:793
at measureLifeCyclePerf (ReactCompositeComponent.js:73)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:792)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:819)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:359)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:255)
at Object.mountComponent (ReactReconciler.js:43)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:368)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:255

适当的Events.js文件的代码

import React, {PureComponent} from 'react';
import marked from 'marked'
import {createStructuredSelector} from 'reselect';
import {connect} from 'react-redux';
import $ from 'jquery'
import moment from 'moment'
import {analytics} from '../../../utils/trackingHelpers';
import {load_contentful} from '../actions';
import {selectEventClasses} from '../selectors';

export class EventClasses extends PureComponent {

    componentDidMount(){
        const {dispatch, load_contentful} = this.props;
        dispatch(load_contentful());
    }

    render(){
        const {events} = this.props;
        //Setting values in nextClass field
        events.map((e) => {
            e.nextClass = {};
            var sDate = new Date(e.startTime);
            e.startDateTime = sDate;
            var options = {weekday: 'short', year: 'numeric', month: 'long', day: 'numeric'};
            var sDateStr = sDate.toLocaleDateString('en-US', options);
            e.nextClass.day = sDateStr.split(', ')[0];

            var dateOptions = {year: 'numeric', month: 'long', day: 'numeric'};
            e.nextClass.date = sDate.toLocaleDateString('en-US', dateOptions);

            var eDate = new Date(e.endTime);
            var dayOptions = {year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', hc: 'h12'};
            var startTime = sDate.toLocaleDateString('en-US', dayOptions);
            var endTime = eDate.toLocaleDateString('en-US', dayOptions);


            var startTimeArr = startTime.split(' ');
            var endTimeArr = endTime.split(' ');
            var startTimeStr = startTimeArr[3].length==4?'0'+startTimeArr[3]:startTimeArr[3];
            var endTimeStr = endTimeArr[3].length==4?'0'+endTimeArr[3]:endTimeArr[3];
            e.nextClass.time = startTimeStr+' '+startTimeArr[4]+' - '+endTimeStr+' '+endTimeArr[4]; 
            e.nextClass.location = e.location; 
            return e;
        });
        //Sorting the events array in ascending order of startDateTime
        var key = 'startDateTime';
        events.sort(function(a, b) {
            var x = a[key] == null? "":a[key]; 
            var y = b[key] == null? "":b[key]; 
            return x < y ? -1 : x > y ? 1 : 0;
        });

        return <div>
        {events.map((event, index) =>
            <div key={`events${index}`} className="event">
                    <div className="event-inner">
                        <div className="event-details">
                            <h2 className={`event-title title-icon-${event.icon}`}>
                                {event.title}
                            </h2>
                            <div className="event-meta">
                                <ul>
                                    <li>Introductory Fee: ${event.fee}</li>
                                    <li>Location: {event.location}</li>
                                    <li>Instructor: {event.instructor}</li>
                                </ul>
                                {event.allClasses ? <a className="event-all-dates">See All Class Dates</a> : null}
                            </div>
                            <div className="event-description" dangerouslySetInnerHTML={{__html: marked(event.description)}}/>
                        </div>
                        <div className="event-other">
                            <div className="event-other-inner">
                                <div className="event-next-class">
                                    <div className="event-next-class-inner">
                                        <h2 className="event-next-class-title">Info</h2>
                                        <div className="event-next-class-description">
                                            <ul>
                                                <li>{event.nextClass.day} | {event.nextClass.date}</li>
                                                <li>{event.nextClass.time}</li>
                                                <li>Location: {event.nextClass.location}</li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                                <div className="event-cta">
                                    <a href={event.link} target="_blank" onClick={() => analytics('event', `Classes:click:Book This Class (${event.title} - ${event.nextClass.date}) CTA`)} className="btn btn__secondary btn__lg btn__uppercase event-cta-btn">Book This Class</a>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>)
        }
        </div>
    }
}

//export default Events;

const mapStateToProps = createStructuredSelector({
    events: selectEventClasses()
});

function mapDispatchToProps(dispatch) {
    return {
        dispatch,
        load_contentful
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(EventClasses);

2 个答案:

答案 0 :(得分:0)

  1. 您必须将状态传递给选择器。
  2. 您可以检查事件是否已定义,因此您将无法使用undefined进行映射。
  3. 避免渲染上的所有计算。渲染应该渲染组件,而不是进行所有这些计算。

答案 1 :(得分:0)

尝试设置默认道具

EventClasses.defaultProps = {
    events: []
}